svn commit: r218075 - in head/sys/powerpc: include mambo mpc85xx powermac powerpc ps3 psim

Marcel Moolenaar marcel at FreeBSD.org
Sat Jan 29 20:58:38 UTC 2011


Author: marcel
Date: Sat Jan 29 20:58:38 2011
New Revision: 218075
URL: http://svn.freebsd.org/changeset/base/218075

Log:
  Fix the interrupt code, broken 7 months ago. The interrupt framework
  already supported nested PICs, but was limited to having a nested
  AT-PIC only. With G5 support the need for nested OpenPIC controllers
  needed to be added. This was done the wrong way and broke the MPC8555
  eval system in the process.
  
  OFW, as well as FDT, describe the interrupt routing in terms of a
  controller and an interrupt pin on it. This needs to be mapped to a
  flat and global resource: the IRQ. The IRQ is the same as the PCI
  intline and as such needs to be representable in 8 bits. Secondly,
  ISA support pretty much dictates that IRQ 0-15 should be reserved
  for ISA interrupts, because of the internal workins of south bridges.
  Both were broken.
  
  This change reverts revision 209298 for a big part and re-implements
  it simpler. In particular:
  o   The id() method of the PIC I/F is removed again. It's not needed.
  o   The openpic_attach() function has been changed to take the OFW
      or FDT phandle of the controller as a second argument. All bus
      attachments that previously used openpic_attach() as the attach
      method of the device I/F now implement as bus-specific method
      and pass the phandle_t to the renamed openpic_attach().
  o   Change powerpc_register_pic() to take a few more arguments. In
      particular:
      -   Pass the number of IPIs specificly. The number of IRQs carved
  	out for a PIC is the sum of the number of int. pins and IPIs.
      -   Pass a flag indicating whether the PIC is an AT-PIC or not.
  	This tells the interrupt framework whether to assign IRQ 0-15
  	or some other range.
  o   Until we implement proper multi-pass bus enumeration, we have to
      handle the case where we need to map from PIC+pin to IRQ *before*
      the PIC gets registered. This is done in a similar way as before,
      but rather than carving out 256 IRQs per PIC, we carve out 128
      IRQs (124 pins + 4 IPIs). This is supposed to handle the G5 case,
      but should really be fixed properly using multiple passes.
  o   Have the interrupt framework set root_pic in most cases and not
      put that burden in PIC drivers (for the most part).
  o   Remove powerpc_ign_lookup() and replace it with powerpc_get_irq().
      Remove IGN_SHIFT, INTR_INTLINE and INTR_IGN.
  
  Related to the above, fix the Freescale PCI controller driver, broken
  by the FDT code. Besides not attaching properly, bus numbers were
  assigned improperly and enumeration was broken in general. This
  prevented the AT PIC from being discovered and interrupt routing to
  work properly. Consequently, the ata(4) controller stopped functioning.
  
  Fix the driver, and FDT PCI support, enough to get the MPC8555CDS
  going again. The FDT PCI code needs a whole lot more work.
  
  No breakages are expected, but lackiong G5 hardware, it's possible
  that there are unpleasant side-effects. At least MPC85xx support is
  back to where it was 7 months ago -- it's amazing how badly support
  can be broken in just 7 months...
  
  Sponsored by: Juniper Networks

Modified:
  head/sys/powerpc/include/intr_machdep.h
  head/sys/powerpc/include/openpicvar.h
  head/sys/powerpc/mambo/mambo_openpic.c
  head/sys/powerpc/mpc85xx/atpic.c
  head/sys/powerpc/mpc85xx/isa.c
  head/sys/powerpc/mpc85xx/openpic_fdt.c
  head/sys/powerpc/mpc85xx/pci_fdt.c
  head/sys/powerpc/powermac/cpcht.c
  head/sys/powerpc/powermac/hrowpic.c
  head/sys/powerpc/powermac/openpic_macio.c
  head/sys/powerpc/powerpc/intr_machdep.c
  head/sys/powerpc/powerpc/openpic.c
  head/sys/powerpc/powerpc/pic_if.m
  head/sys/powerpc/ps3/ps3pic.c
  head/sys/powerpc/psim/openpic_iobus.c

Modified: head/sys/powerpc/include/intr_machdep.h
==============================================================================
--- head/sys/powerpc/include/intr_machdep.h	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/include/intr_machdep.h	Sat Jan 29 20:58:38 2011	(r218075)
@@ -29,13 +29,9 @@
 #define	_MACHINE_INTR_MACHDEP_H_
 
 #define	INTR_VECTORS	256
-#define	MAX_PICS	5
 
-#define	IGN_SHIFT	8
-#define	INTR_INTLINE(irq) (irq & ((1 << IGN_SHIFT) - 1))
-#define	INTR_IGN(irq)	(irq >> IGN_SHIFT)
-
-#define	INTR_VEC(pic_id, irq) ((powerpc_ign_lookup(pic_id) << IGN_SHIFT) | (irq))
+#define	MAX_PICS		5
+#define	INTR_VEC(node, pin)	powerpc_get_irq(node, pin)
 
 /*
  * Default base address for MSI messages on PowerPC
@@ -50,8 +46,8 @@ driver_filter_t powerpc_ipi_handler;
 
 void	intrcnt_add(const char *name, u_long **countp);
 
-void	powerpc_register_pic(device_t, u_int);
-int	powerpc_ign_lookup(uint32_t pic_id);
+void	powerpc_register_pic(device_t, uint32_t, u_int, u_int, u_int);
+u_int	powerpc_get_irq(uint32_t, u_int);
 
 void	powerpc_dispatch_intr(u_int, struct trapframe *);
 int	powerpc_enable_intr(void);

Modified: head/sys/powerpc/include/openpicvar.h
==============================================================================
--- head/sys/powerpc/include/openpicvar.h	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/include/openpicvar.h	Sat Jan 29 20:58:38 2011	(r218075)
@@ -52,7 +52,7 @@ extern devclass_t openpic_devclass;
 /*
  * Bus-independent attach i/f
  */
-int	openpic_attach(device_t);
+int	openpic_common_attach(device_t, uint32_t);
 
 /*
  * PIC interface.

Modified: head/sys/powerpc/mambo/mambo_openpic.c
==============================================================================
--- head/sys/powerpc/mambo/mambo_openpic.c	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/mambo/mambo_openpic.c	Sat Jan 29 20:58:38 2011	(r218075)
@@ -56,12 +56,11 @@ __FBSDID("$FreeBSD$");
  * Mambo interface
  */
 static int	openpic_mambo_probe(device_t);
-static uint32_t	openpic_mambo_id(device_t dev);
+static int	openpic_mambo_attach(device_t);
 static int	openpicbus_mambo_probe(device_t dev);
 static int	openpicbus_mambo_attach(device_t dev);
-static struct resource *openpicbus_alloc_resource(device_t bus, device_t dev, 
-		    int type, int *rid, u_long start, u_long end, u_long count, 
-		    u_int flags);
+static struct resource *openpicbus_alloc_resource(device_t bus, device_t dev,
+    int type, int *rid, u_long start, u_long end, u_long count, u_int flags);
 
 static device_method_t  openpicbus_mambo_methods[] = {
 	/* Device interface */
@@ -87,7 +86,7 @@ static driver_t openpicbus_mambo_driver 
 static device_method_t  openpic_mambo_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		openpic_mambo_probe),
-	DEVMETHOD(device_attach,	openpic_attach),
+	DEVMETHOD(device_attach,	openpic_mambo_attach),
 
 	/* PIC interface */
 	DEVMETHOD(pic_config,		openpic_config),
@@ -97,7 +96,6 @@ static device_method_t  openpic_mambo_me
 	DEVMETHOD(pic_ipi,		openpic_ipi),
 	DEVMETHOD(pic_mask,		openpic_mask),
 	DEVMETHOD(pic_unmask,		openpic_unmask),
-	DEVMETHOD(pic_id,		openpic_mambo_id),
 
 	{ 0, 0 },
 };
@@ -167,14 +165,15 @@ openpicbus_alloc_resource(device_t bus, 
 static int
 openpic_mambo_probe(device_t dev)
 {
+
 	device_set_desc(dev, OPENPIC_DEVSTR);
-	
 	return (0);
 }
 
-static uint32_t
-openpic_mambo_id(device_t dev)
+static int
+openpic_mambo_attach(device_t dev)
 {
-	return (ofw_bus_get_node(device_get_parent(dev)));
+ 
+	return (openpic_common_attach(dev,
+	    ofw_bus_get_node(device_get_parent(dev))));
 }
-

Modified: head/sys/powerpc/mpc85xx/atpic.c
==============================================================================
--- head/sys/powerpc/mpc85xx/atpic.c	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/mpc85xx/atpic.c	Sat Jan 29 20:58:38 2011	(r218075)
@@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/bus.h>
 #include <machine/intr_machdep.h>
-#include <machine/ocpbus.h>
 #include <machine/pio.h>
 
 #include <powerpc/mpc85xx/mpc85xx.h>
@@ -79,7 +78,6 @@ static void atpic_eoi(device_t, u_int);
 static void atpic_ipi(device_t, u_int);
 static void atpic_mask(device_t, u_int);
 static void atpic_unmask(device_t, u_int);
-static uint32_t atpic_id (device_t dev);
 
 static device_method_t atpic_isa_methods[] = {
 	/* Device interface */
@@ -95,7 +93,6 @@ static device_method_t atpic_isa_methods
 	DEVMETHOD(pic_ipi,		atpic_ipi),
 	DEVMETHOD(pic_mask,		atpic_mask),
 	DEVMETHOD(pic_unmask,		atpic_unmask),
-	DEVMETHOD(pic_id,		atpic_id),
 
 	{ 0, 0 },
 };
@@ -154,7 +151,7 @@ atpic_isa_identify(driver_t *drv, device
 	bus_set_resource(child, SYS_RES_IOPORT, ATPIC_SLAVE, IO_ICU2, 2);
 
 	/* ISA interrupts are routed through external interrupt 0. */
-	bus_set_resource(child, SYS_RES_IRQ, 0, PIC_IRQ_EXT(0), 1);
+	bus_set_resource(child, SYS_RES_IRQ, 0, 16, 1);
 }
 
 static int
@@ -221,7 +218,7 @@ atpic_isa_attach(device_t dev)
 	atpic_init(sc, ATPIC_SLAVE);
 	atpic_init(sc, ATPIC_MASTER);
 
-	powerpc_register_pic(dev, 0x10);
+	powerpc_register_pic(dev, 0, 16, 0, TRUE);
 	return (0);
 
  fail:
@@ -328,11 +325,3 @@ atpic_unmask(device_t dev, u_int irq)
 		atpic_write(sc, ATPIC_MASTER, 1, sc->sc_mask[ATPIC_MASTER]);
 	}
 }
-
-static uint32_t
-atpic_id (device_t dev)
-{
-
-	return (ATPIC_ID);
-}
-

Modified: head/sys/powerpc/mpc85xx/isa.c
==============================================================================
--- head/sys/powerpc/mpc85xx/isa.c	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/mpc85xx/isa.c	Sat Jan 29 20:58:38 2011	(r218075)
@@ -33,15 +33,12 @@ __FBSDID("$FreeBSD$");
 #include <sys/rman.h>
 
 #include <machine/intr_machdep.h>
-#include <machine/ocpbus.h>
 #include <machine/resource.h>
 
 #include <isa/isareg.h>
 #include <isa/isavar.h>
 #include <isa/isa_common.h>
 
-#include "ocpbus.h"
-
 void
 isa_init(device_t dev)
 {
@@ -62,10 +59,7 @@ isa_alloc_resource(device_t bus, device_
 	    resource_list_find(rl, type, *rid) == NULL) {
 		switch (type) {
 		case SYS_RES_IOPORT:	rids = ISA_PNP_NPORT; break;
-		case SYS_RES_IRQ:
-			rids = ISA_PNP_NIRQ;
-			start = ISA_IRQ(start);
-			break;
+		case SYS_RES_IRQ:	rids = ISA_PNP_NIRQ; break;
 		case SYS_RES_MEMORY:	rids = ISA_PNP_NMEM; break;
 		default:		rids = 0; break;
 		}

Modified: head/sys/powerpc/mpc85xx/openpic_fdt.c
==============================================================================
--- head/sys/powerpc/mpc85xx/openpic_fdt.c	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/mpc85xx/openpic_fdt.c	Sat Jan 29 20:58:38 2011	(r218075)
@@ -45,12 +45,12 @@ __FBSDID("$FreeBSD$");
 #include "pic_if.h"
 
 static int openpic_fdt_probe(device_t);
-static uint32_t openpic_fdt_id(device_t);
+static int openpic_fdt_attach(device_t);
 
 static device_method_t openpic_fdt_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		openpic_fdt_probe),
-	DEVMETHOD(device_attach,	openpic_attach),
+	DEVMETHOD(device_attach,	openpic_fdt_attach),
 
 	/* PIC interface */
 	DEVMETHOD(pic_bind,		openpic_bind),
@@ -61,7 +61,6 @@ static device_method_t openpic_fdt_metho
 	DEVMETHOD(pic_ipi,		openpic_ipi),
 	DEVMETHOD(pic_mask,		openpic_mask),
 	DEVMETHOD(pic_unmask,		openpic_unmask),
-	DEVMETHOD(pic_id,		openpic_fdt_id),
 
 	{ 0, 0 },
 };
@@ -85,9 +84,9 @@ openpic_fdt_probe(device_t dev)
 	return (BUS_PROBE_DEFAULT);
 }
 
-static uint32_t
-openpic_fdt_id(device_t dev)
+static int
+openpic_fdt_attach(device_t dev)
 {
 
-	return (ofw_bus_get_node(dev));
+	return (openpic_common_attach(dev, ofw_bus_get_node(dev)));
 }

Modified: head/sys/powerpc/mpc85xx/pci_fdt.c
==============================================================================
--- head/sys/powerpc/mpc85xx/pci_fdt.c	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/mpc85xx/pci_fdt.c	Sat Jan 29 20:58:38 2011	(r218075)
@@ -136,7 +136,7 @@ static int fsl_pcib_decode_win(phandle_t
 static void fsl_pcib_err_init(device_t);
 static void fsl_pcib_inbound(struct fsl_pcib_softc *, int, int, u_long,
     u_long, u_long);
-static int fsl_pcib_init(struct fsl_pcib_softc *, int, int, int);
+static int fsl_pcib_init(struct fsl_pcib_softc *, int, int);
 static int fsl_pcib_intr_info(phandle_t, struct fsl_pcib_softc *);
 static int fsl_pcib_set_range(struct fsl_pcib_softc *, int, int, u_long,
     u_long);
@@ -160,8 +160,6 @@ static uint32_t fsl_pcib_read_config(dev
 static void fsl_pcib_write_config(device_t, u_int, u_int, u_int, u_int,
     uint32_t, int);
 
-static int next_busnr = 0;
-
 /* Configuration r/w mutex. */
 struct mtx pcicfg_mtx;
 static int mtx_initialized = 0;
@@ -215,23 +213,17 @@ DRIVER_MODULE(pcib, fdtbus, fsl_pcib_dri
 static int
 fsl_pcib_probe(device_t dev)
 {
-	phandle_t parnode;
+	phandle_t node;
 
-	/*
-	 * The PCI subnode does not have the 'compatible' property, so we need
-	 * to check in the parent PCI node. However the parent is not
-	 * represented by a separate ofw_bus child, and therefore
-	 * ofw_bus_is_compatible() cannot be used, but direct fdt equivalent.
-	 */
-	parnode = OF_parent(ofw_bus_get_node(dev));
-	if (parnode == 0)
+	node = ofw_bus_get_node(dev);
+	if (!fdt_is_type(node, "pci"))
 		return (ENXIO);
-	if (!(fdt_is_compatible(parnode, "fsl,mpc8548-pcie") ||
-	    fdt_is_compatible(parnode, "fsl,mpc8548-pcie")))
+
+	if (!(fdt_is_compatible(node, "fsl,mpc8540-pci") ||
+	    fdt_is_compatible(node, "fsl,mpc8548-pcie")))
 		return (ENXIO);
 
 	device_set_desc(dev, "Freescale Integrated PCI/PCI-E Controller");
-
 	return (BUS_PROBE_DEFAULT);
 }
 
@@ -241,7 +233,7 @@ fsl_pcib_attach(device_t dev)
 	struct fsl_pcib_softc *sc;
 	phandle_t node;
 	uint32_t cfgreg;
-	int maxslot, subbus;
+	int maxslot;
 	uint8_t ltssm, capptr;
 
 	sc = device_get_softc(dev);
@@ -304,23 +296,13 @@ fsl_pcib_attach(device_t dev)
 	sc->sc_devfn_tundra = -1;
 	sc->sc_devfn_via_ide = -1;
 
-	maxslot = (sc->sc_pcie) ? 1 : 31;
 
 	/*
-	 * Scan bus using firmware configured, 0 based bus numbering,
-	 * let fsl_pcib_init() shift bus number by next_busnr offset.
+	 * Scan bus using firmware configured, 0 based bus numbering.
 	 */
-	sc->sc_busnr = 1;
-	subbus = fsl_pcib_init(sc, 0, next_busnr, maxslot);
-
-	if (bootverbose)
-		printf("PCI: domain %d, busnr = %d, next_busnr = %d\n",
-		    device_get_unit(dev), next_busnr + 1,
-		    next_busnr + subbus + 1);
-
-	/* Set final busnr */
-	sc->sc_busnr = next_busnr + 1;
-	next_busnr += subbus + 1;
+	sc->sc_busnr = 0;
+	maxslot = (sc->sc_pcie) ? 0 : PCI_SLOTMAX;
+	fsl_pcib_init(sc, sc->sc_busnr, maxslot);
 
 	if (sc->sc_pcie) {
 		ltssm = fsl_pcib_cfgread(sc, 0, 0, 0, PCIR_LTSSM, 1);
@@ -455,7 +437,7 @@ fsl_pcib_maxslots(device_t dev)
 {
 	struct fsl_pcib_softc *sc = device_get_softc(dev);
 
-	return ((sc->sc_pcie) ? 1 : 31);
+	return ((sc->sc_pcie) ? 0 : PCI_SLOTMAX);
 }
 
 static uint32_t
@@ -572,14 +554,11 @@ fsl_pcib_route_int(struct fsl_pcib_softc
 
 	devfn = DEVFN(bus, slot, func);
 	if (devfn == sc->sc_devfn_via_ide)
-#if 0
-		intline = INTR_VEC(ATPIC_ID, 14);
+		intline = INTR_VEC(0, 14);
 	else if (devfn == sc->sc_devfn_via_ide + 1)
-		intline = INTR_VEC(ATPIC_ID, 10);
+		intline = INTR_VEC(0, 10);
 	else if (devfn == sc->sc_devfn_via_ide + 2)
-		intline = INTR_VEC(ATPIC_ID, 10);
-#endif
-		;
+		intline = INTR_VEC(0, 10);
 	else {
 		if (intpin != 0)
 			err = fdt_pci_route_intr(bus, slot, func, intpin,
@@ -596,10 +575,9 @@ fsl_pcib_route_int(struct fsl_pcib_softc
 }
 
 static int
-fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int busnr_offset,
-    int maxslot)
+fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int maxslot)
 {
-	int secbus, subbus;
+	int secbus;
 	int old_pribus, old_secbus, old_subbus;
 	int new_pribus, new_secbus, new_subbus;
 	int slot, func, maxfunc;
@@ -608,11 +586,10 @@ fsl_pcib_init(struct fsl_pcib_softc *sc,
 	uint8_t command, hdrtype, class, subclass;
 	uint8_t intline, intpin;
 
-	subbus = bus;
+	secbus = bus;
 	for (slot = 0; slot <= maxslot; slot++) {
 		maxfunc = 0;
 		for (func = 0; func <= maxfunc; func++) {
-
 			hdrtype = fsl_pcib_read_config(sc->sc_dev, bus, slot,
 			    func, PCIR_HDRTYPE, 1);
 
@@ -667,19 +644,14 @@ fsl_pcib_init(struct fsl_pcib_softc *sc,
 			    func, PCIR_CLASS, 1);
 			subclass = fsl_pcib_read_config(sc->sc_dev, bus, slot,
 			    func, PCIR_SUBCLASS, 1);
-#if 0
+
 			/* Allow only proper PCI-PCI briges */
 			if (class != PCIC_BRIDGE)
 				continue;
 			if (subclass != PCIS_BRIDGE_PCI)
 				continue;
-#endif
-			/* Allow all DEVTYPE 1 devices */
-			if (hdrtype != PCIM_HDRTYPE_BRIDGE)
-				continue;
 
-			subbus++;
-			secbus = subbus;
+			secbus++;
 
 			/* Program I/O decoder. */
 			fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
@@ -718,31 +690,20 @@ fsl_pcib_init(struct fsl_pcib_softc *sc,
 			if (bootverbose)
 				printf("PCI: reading firmware bus numbers for "
 				    "secbus = %d (bus/sec/sub) = (%d/%d/%d)\n",
-				    secbus + busnr_offset, old_pribus,
-				    old_secbus, old_subbus);
+				    secbus, old_pribus, old_secbus, old_subbus);
 
-			/* Skip unconfigured devices */
-			if ((old_pribus == 0) &&
-			    (old_secbus == 0) && (old_subbus == 0))
-				continue;
+			new_pribus = bus;
+			new_secbus = secbus;
 
-			subbus += fsl_pcib_init(sc, secbus, busnr_offset,
-			    (subclass == PCIS_BRIDGE_PCI) ? 31 : 1);
+			secbus = fsl_pcib_init(sc, secbus,
+			    (subclass == PCIS_BRIDGE_PCI) ? PCI_SLOTMAX : 0);
 
-			new_pribus = bus + busnr_offset;
-			new_secbus = secbus + busnr_offset;
-			new_subbus = subbus + busnr_offset;
-
-			/* Fixup pribus for MPC8572 PCIE controller */
-			if ((vendor == 0x1957) && ((device = 0x0040) ||
-			    (device == 0x0041)))
-				new_pribus = 0;
+			new_subbus = secbus;
 
 			if (bootverbose)
-				printf("PCI: translate firmware bus numbers for "
-				    "secbus %d (%d/%d/%d) -> (%d/%d/%d)\n",
-				    secbus + busnr_offset,
-				    old_pribus, old_secbus, old_subbus,
+				printf("PCI: translate firmware bus numbers "
+				    "for secbus %d (%d/%d/%d) -> (%d/%d/%d)\n",
+				    secbus, old_pribus, old_secbus, old_subbus,
 				    new_pribus, new_secbus, new_subbus);
 
 			fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
@@ -754,11 +715,7 @@ fsl_pcib_init(struct fsl_pcib_softc *sc,
 		}
 	}
 
-	if (bootverbose)
-		printf("PCI: bus %d, #subbus = %d\n",
-		    bus + busnr_offset, subbus - bus);
-
-	return (subbus - bus);
+	return (secbus);
 }
 
 static void
@@ -938,12 +895,10 @@ fsl_pcib_alloc_resource(device_t dev, de
 		va = sc->sc_iomem_va;
 		break;
 	case SYS_RES_IRQ:
-#if 0
-		if (INTR_IGN(start) == powerpc_ign_lookup(ATPIC_ID)) {
+		if (start < 16) {
 			device_printf(dev, "%s requested ISA interrupt %lu\n",
 			    device_get_nameunit(child), start);
 		}
-#endif
 		flags |= RF_SHAREABLE;
 		return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
 		    type, rid, start, end, count, flags));

Modified: head/sys/powerpc/powermac/cpcht.c
==============================================================================
--- head/sys/powerpc/powermac/cpcht.c	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/powermac/cpcht.c	Sat Jan 29 20:58:38 2011	(r218075)
@@ -757,7 +757,6 @@ static void	openpic_cpcht_config(device_
 static void	openpic_cpcht_enable(device_t, u_int irq, u_int vector);
 static void	openpic_cpcht_unmask(device_t, u_int irq);
 static void	openpic_cpcht_eoi(device_t, u_int irq);
-static uint32_t	openpic_cpcht_id(device_t);
 
 static device_method_t  openpic_cpcht_methods[] = {
 	/* Device interface */
@@ -773,7 +772,6 @@ static device_method_t  openpic_cpcht_me
 	DEVMETHOD(pic_ipi,		openpic_ipi),
 	DEVMETHOD(pic_mask,		openpic_mask),
 	DEVMETHOD(pic_unmask,		openpic_cpcht_unmask),
-	DEVMETHOD(pic_id,		openpic_cpcht_id),
 
 	{ 0, 0 },
 };
@@ -808,9 +806,11 @@ static int
 openpic_cpcht_attach(device_t dev)
 {
 	struct openpic_cpcht_softc *sc;
+	phandle_t node;
 	int err, irq;
 
-	err = openpic_attach(dev);
+	node = ofw_bus_get_node(dev);
+	err = openpic_common_attach(dev, node);
 	if (err != 0)
 		return (err);
 
@@ -839,9 +839,8 @@ openpic_cpcht_attach(device_t dev)
 	 * be necessary, but Linux does it, and I cannot find any U3 machines
 	 * with MSI devices to test.
 	 */
-	
 	if (dev == root_pic)
-		cpcht_msipic = PIC_ID(dev);
+		cpcht_msipic = node;
 
 	return (0);
 }
@@ -981,10 +980,3 @@ openpic_cpcht_eoi(device_t dev, u_int ir
 
 	openpic_eoi(dev, irq);
 }
-
-static uint32_t
-openpic_cpcht_id(device_t dev)
-{
-	return (ofw_bus_get_node(dev));
-}
-

Modified: head/sys/powerpc/powermac/hrowpic.c
==============================================================================
--- head/sys/powerpc/powermac/hrowpic.c	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/powermac/hrowpic.c	Sat Jan 29 20:58:38 2011	(r218075)
@@ -69,7 +69,6 @@ static void	hrowpic_eoi(device_t, u_int)
 static void	hrowpic_ipi(device_t, u_int);
 static void	hrowpic_mask(device_t, u_int);
 static void	hrowpic_unmask(device_t, u_int);
-static uint32_t hrowpic_id(device_t dev);
 
 static device_method_t  hrowpic_methods[] = {
 	/* Device interface */
@@ -80,7 +79,6 @@ static device_method_t  hrowpic_methods[
 	DEVMETHOD(pic_dispatch,		hrowpic_dispatch),
 	DEVMETHOD(pic_enable,		hrowpic_enable),
 	DEVMETHOD(pic_eoi,		hrowpic_eoi),
-	DEVMETHOD(pic_id,		hrowpic_id),
 	DEVMETHOD(pic_ipi,		hrowpic_ipi),
 	DEVMETHOD(pic_mask,		hrowpic_mask),
 	DEVMETHOD(pic_unmask,		hrowpic_unmask),
@@ -169,9 +167,7 @@ hrowpic_attach(device_t dev)
 	hrowpic_write_reg(sc, HPIC_ENABLE, HPIC_SECONDARY, 0);
 	hrowpic_write_reg(sc, HPIC_CLEAR,  HPIC_SECONDARY, 0xffffffff);
 
-	powerpc_register_pic(dev, 64);
-	root_pic = dev; /* Heathrow systems have only one PIC */
-
+	powerpc_register_pic(dev, ofw_bus_get_node(dev), 64, 0, FALSE);
 	return (0);
 }
 
@@ -282,10 +278,3 @@ hrowpic_unmask(device_t dev, u_int irq)
 	sc = device_get_softc(dev);
 	hrowpic_toggle_irq(sc, irq, 1);
 }
-
-static uint32_t
-hrowpic_id(device_t dev)
-{
-	return (ofw_bus_get_node(dev));
-}
-

Modified: head/sys/powerpc/powermac/openpic_macio.c
==============================================================================
--- head/sys/powerpc/powermac/openpic_macio.c	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/powermac/openpic_macio.c	Sat Jan 29 20:58:38 2011	(r218075)
@@ -58,12 +58,12 @@ __FBSDID("$FreeBSD$");
  * MacIO interface
  */
 static int	openpic_macio_probe(device_t);
-static uint32_t	openpic_macio_id(device_t);
+static int	openpic_macio_attach(device_t);
 
 static device_method_t  openpic_macio_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		openpic_macio_probe),
-	DEVMETHOD(device_attach,	openpic_attach),
+	DEVMETHOD(device_attach,	openpic_macio_attach),
 
 	/* PIC interface */
 	DEVMETHOD(pic_bind,		openpic_bind),
@@ -74,7 +74,6 @@ static device_method_t  openpic_macio_me
 	DEVMETHOD(pic_ipi,		openpic_ipi),
 	DEVMETHOD(pic_mask,		openpic_mask),
 	DEVMETHOD(pic_unmask,		openpic_unmask),
-	DEVMETHOD(pic_id,		openpic_macio_id),
 
 	{ 0, 0 },
 };
@@ -99,9 +98,9 @@ openpic_macio_probe(device_t dev)
 	return (0);
 }
 
-static uint32_t
-openpic_macio_id(device_t dev)
+static int
+openpic_macio_attach(device_t dev)
 {
-	return (ofw_bus_get_node(dev));
+ 
+	return (openpic_common_attach(dev, ofw_bus_get_node(dev)));
 }
-

Modified: head/sys/powerpc/powerpc/intr_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/intr_machdep.c	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/powerpc/intr_machdep.c	Sat Jan 29 20:58:38 2011	(r218075)
@@ -60,6 +60,8 @@
  * $FreeBSD$
  */
 
+#include "opt_isa.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -102,9 +104,11 @@ struct powerpc_intr {
 };
 
 struct pic {
-	device_t pic;
-	uint32_t pic_id;
-	int ipi_irq;
+	device_t dev;
+	uint32_t node;
+	u_int	irqs;
+	u_int	ipis;
+	int	base;
 };
 
 static u_int intrcnt_index = 0;
@@ -113,6 +117,11 @@ static struct powerpc_intr *powerpc_intr
 static struct pic piclist[MAX_PICS];
 static u_int nvectors;		/* Allocated vectors */
 static u_int npics;		/* PICs registered */
+#ifdef DEV_ISA
+static u_int nirqs = 16;	/* Allocated IRQS (ISA pre-allocated). */
+#else
+static u_int nirqs = 0;		/* Allocated IRQs. */
+#endif
 static u_int stray_count;
 
 device_t root_pic;
@@ -142,7 +151,6 @@ smp_intr_init(void *dummy __unused)
 			PIC_BIND(i->pic, i->intline, i->cpu);
 	}
 }
-
 SYSINIT(smp_intr_init, SI_SUB_SMP, SI_ORDER_ANY, smp_intr_init, NULL);
 #endif
 
@@ -231,9 +239,21 @@ intr_lookup(u_int irq)
 static int
 powerpc_map_irq(struct powerpc_intr *i)
 {
+	struct pic *p;
+	u_int cnt;
+	int idx;
+
+	for (idx = 0; idx < npics; idx++) {
+		p = &piclist[idx];
+		cnt = p->irqs + p->ipis;
+		if (i->irq >= p->base && i->irq < p->base + cnt)
+			break;
+	}
+	if (idx == npics)
+		return (EINVAL);
 
-	i->intline = INTR_INTLINE(i->irq);
-	i->pic = piclist[INTR_IGN(i->irq)].pic;
+	i->intline = i->irq - p->base;
+	i->pic = p->dev;
 
 	/* Try a best guess if that failed */
 	if (i->pic == NULL)
@@ -288,46 +308,76 @@ powerpc_assign_intr_cpu(void *arg, u_cha
 }
 
 void
-powerpc_register_pic(device_t dev, u_int ipi)
+powerpc_register_pic(device_t dev, uint32_t node, u_int irqs, u_int ipis,
+    u_int atpic)
 {
-	int i;
+	struct pic *p;
+	u_int irq;
+	int idx;
 
 	mtx_lock(&intr_table_lock);
 
-	for (i = 0; i < npics; i++) {
-		if (piclist[i].pic_id == PIC_ID(dev))
+	/* XXX see powerpc_get_irq(). */
+	for (idx = 0; idx < npics; idx++) {
+		p = &piclist[idx];
+		if (p->node != node)
+			continue;
+		if (node != 0 || p->dev == dev)
 			break;
 	}
-	piclist[i].pic = dev;
-	piclist[i].pic_id = PIC_ID(dev);
-	piclist[i].ipi_irq = ipi;
-	if (i == npics)
+	p = &piclist[idx];
+
+	p->dev = dev;
+	p->node = node;
+	p->irqs = irqs;
+	p->ipis = ipis;
+	if (idx == npics) {
+#ifdef DEV_ISA
+		p->base = (atpic) ? 0 : nirqs;
+#else
+		p->base = nirqs;
+#endif
+		irq = p->base + irqs + ipis;
+		nirqs = MAX(nirqs, irq);
 		npics++;
+	}
 
 	mtx_unlock(&intr_table_lock);
 }
 
-int
-powerpc_ign_lookup(uint32_t pic_id)
+u_int
+powerpc_get_irq(uint32_t node, u_int pin)
 {
-	int i;
+	int idx;
 
-	mtx_lock(&intr_table_lock);
+	if (node == 0)
+		return (pin);
 
-	for (i = 0; i < npics; i++) {
-		if (piclist[i].pic_id == pic_id) {
+	mtx_lock(&intr_table_lock);
+	for (idx = 0; idx < npics; idx++) {
+		if (piclist[idx].node == node) {
 			mtx_unlock(&intr_table_lock);
-			return (i);
+			return (piclist[idx].base + pin);
 		}
 	}
-	piclist[i].pic = NULL;
-	piclist[i].pic_id = pic_id;
-	piclist[i].ipi_irq = 0;
+
+	/*
+	 * XXX we should never encounter an unregistered PIC, but that
+	 * can only be done when we properly support bus enumeration
+	 * using multiple passes. Until then, fake an entry and give it
+	 * some adhoc maximum number of IRQs and IPIs.
+	 */
+	piclist[idx].dev = NULL;
+	piclist[idx].node = node;
+	piclist[idx].irqs = 124;
+	piclist[idx].ipis = 4;
+	piclist[idx].base = nirqs;
+	nirqs += 128;
 	npics++;
 
 	mtx_unlock(&intr_table_lock);
 
-	return (i);
+	return (piclist[idx].base + pin);
 }
 
 int
@@ -342,15 +392,18 @@ powerpc_enable_intr(void)
 	if (npics == 0)
 		panic("no PIC detected\n");
 
+	if (root_pic == NULL)
+		root_pic = piclist[0].dev;
+
 #ifdef SMP
 	/* Install an IPI handler. */
-
 	for (n = 0; n < npics; n++) {
-		if (piclist[n].pic != root_pic)
+		if (piclist[n].dev != root_pic)
 			continue;
 
+		KASSERT(piclist[n].ipis != 0, ("%s", __func__));
 		error = powerpc_setup_intr("IPI",
-		    INTR_VEC(piclist[n].pic_id, piclist[n].ipi_irq),
+		    INTR_VEC(piclist[n].node, piclist[n].irqs),
 		    powerpc_ipi_handler, NULL, NULL,
 		    INTR_TYPE_MISC | INTR_EXCL, &ipi_cookie);
 		if (error) {
@@ -373,6 +426,9 @@ powerpc_enable_intr(void)
 		    i->pol != INTR_POLARITY_CONFORM)
 			PIC_CONFIG(i->pic, i->intline, i->trig, i->pol);
 
+		if (i != NULL && i->pic == root_pic)
+			PIC_BIND(i->pic, i->intline, i->cpu);
+
 		if (i->event != NULL)
 			PIC_ENABLE(i->pic, i->intline, vector);
 	}

Modified: head/sys/powerpc/powerpc/openpic.c
==============================================================================
--- head/sys/powerpc/powerpc/openpic.c	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/powerpc/openpic.c	Sat Jan 29 20:58:38 2011	(r218075)
@@ -83,7 +83,7 @@ openpic_set_priority(struct openpic_soft
 }
 
 int
-openpic_attach(device_t dev)
+openpic_common_attach(device_t dev, uint32_t node)
 {
 	struct openpic_softc *sc;
 	u_int     cpu, ipi, irq;
@@ -217,7 +217,7 @@ openpic_attach(device_t dev)
 	for (cpu = 0; cpu < sc->sc_ncpu; cpu++)
 		openpic_write(sc, OPENPIC_PCPU_TPR(cpu), 0);
 
-	powerpc_register_pic(dev, sc->sc_nirq);
+	powerpc_register_pic(dev, node, sc->sc_nirq, 4, FALSE);
 
 	/* If this is not a cascaded PIC, it must be the root PIC */
 	if (sc->sc_intr == NULL)
@@ -285,7 +285,6 @@ openpic_dispatch(device_t dev, struct tr
 	cpuid = (dev == root_pic) ? PCPU_GET(cpuid) : 0;
 
 	sc = device_get_softc(dev);
-
 	while (1) {
 		vector = openpic_read(sc, OPENPIC_PCPU_IACK(cpuid));
 		vector &= OPENPIC_VECTOR_MASK;

Modified: head/sys/powerpc/powerpc/pic_if.m
==============================================================================
--- head/sys/powerpc/powerpc/pic_if.m	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/powerpc/pic_if.m	Sat Jan 29 20:58:38 2011	(r218075)
@@ -66,10 +66,6 @@ METHOD void ipi {
 	u_int		cpu;
 };
 
-METHOD uint32_t id {
-	device_t	dev;
-};
-
 METHOD void mask {
 	device_t	dev;
 	u_int		irq;

Modified: head/sys/powerpc/ps3/ps3pic.c
==============================================================================
--- head/sys/powerpc/ps3/ps3pic.c	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/ps3/ps3pic.c	Sat Jan 29 20:58:38 2011	(r218075)
@@ -54,7 +54,6 @@ static void	ps3pic_eoi(device_t, u_int);
 static void	ps3pic_ipi(device_t, u_int);
 static void	ps3pic_mask(device_t, u_int);
 static void	ps3pic_unmask(device_t, u_int);
-static uint32_t ps3pic_id(device_t dev);
 
 struct ps3pic_softc {
 	uint64_t	*bitmap_thread0;
@@ -76,7 +75,6 @@ static device_method_t  ps3pic_methods[]
 	DEVMETHOD(pic_dispatch,		ps3pic_dispatch),
 	DEVMETHOD(pic_enable,		ps3pic_enable),
 	DEVMETHOD(pic_eoi,		ps3pic_eoi),
-	DEVMETHOD(pic_id,		ps3pic_id),
 	DEVMETHOD(pic_ipi,		ps3pic_ipi),
 	DEVMETHOD(pic_mask,		ps3pic_mask),
 	DEVMETHOD(pic_unmask,		ps3pic_unmask),
@@ -146,9 +144,7 @@ ps3pic_attach(device_t dev)
 	    sc->sc_ipi_outlet[1], 0);
 #endif
 
-	powerpc_register_pic(dev, sc->sc_ipi_outlet[0]);
-	root_pic = dev; /* PS3s have only one PIC */
-
+	powerpc_register_pic(dev, 0, sc->sc_ipi_outlet[0], 1, FALSE);
 	return (0);
 }
 
@@ -245,10 +241,3 @@ ps3pic_unmask(device_t dev, u_int irq)
 	lv1_did_update_interrupt_mask(ppe, 0);
 	lv1_did_update_interrupt_mask(ppe, 1);
 }
-
-static uint32_t
-ps3pic_id(device_t dev)
-{
-	return (0);
-}
-

Modified: head/sys/powerpc/psim/openpic_iobus.c
==============================================================================
--- head/sys/powerpc/psim/openpic_iobus.c	Sat Jan 29 20:28:17 2011	(r218074)
+++ head/sys/powerpc/psim/openpic_iobus.c	Sat Jan 29 20:58:38 2011	(r218075)
@@ -62,11 +62,12 @@ __FBSDID("$FreeBSD$");
  * PSIM IOBus interface
  */
 static int	openpic_iobus_probe(device_t);
+static int	openpic_iobus_attach(device_t);
 
 static device_method_t  openpic_iobus_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		openpic_iobus_probe),
-	DEVMETHOD(device_attach,	openpic_attach),
+	DEVMETHOD(device_attach,	openpic_iobus_attach),
 
 	/* PIC interface */
 	DEVMETHOD(pic_config,		openpic_config),
@@ -109,3 +110,10 @@ openpic_iobus_probe(device_t dev)
 
 	return (0);
 }
+
+static int
+openpic_iobus_attach(device_t dev)
+{
+
+	return (openpic_common_attach(dev, 0));
+}


More information about the svn-src-all mailing list