Module Name:    src
Committed By:   palle
Date:           Sun Aug 24 19:06:14 UTC 2014

Modified Files:
        src/sys/arch/sparc64/dev: ebus_mainbus.c ebusvar.h

Log Message:
Generalize the code to allow for arbitrary interrupt wirings - with this change 
the serial console is usable on Sun Fire V445 systems - from OpenBSD - ok mrg@ 
martin@


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/sparc64/dev/ebus_mainbus.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/sparc64/dev/ebusvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/sparc64/dev/ebus_mainbus.c
diff -u src/sys/arch/sparc64/dev/ebus_mainbus.c:1.12 src/sys/arch/sparc64/dev/ebus_mainbus.c:1.13
--- src/sys/arch/sparc64/dev/ebus_mainbus.c:1.12	Mon Dec 16 20:17:35 2013
+++ src/sys/arch/sparc64/dev/ebus_mainbus.c	Sun Aug 24 19:06:14 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ebus_mainbus.c,v 1.12 2013/12/16 20:17:35 palle Exp $	*/
+/*	$NetBSD: ebus_mainbus.c,v 1.13 2014/08/24 19:06:14 palle Exp $	*/
 /*	$OpenBSD: ebus_mainbus.c,v 1.7 2010/11/11 17:58:23 miod Exp $	*/
 
 /*
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ebus_mainbus.c,v 1.12 2013/12/16 20:17:35 palle Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ebus_mainbus.c,v 1.13 2014/08/24 19:06:14 palle Exp $");
 
 #ifdef DEBUG
 #define	EDB_PROM	0x01
@@ -56,6 +56,8 @@ extern int ebus_debug;
 #include <dev/ebus/ebusvar.h>
 #include <sparc64/dev/ebusvar.h>
 
+extern struct cfdriver pyro_cd;
+
 int	ebus_mainbus_match(device_t, cfdata_t, void *);
 void	ebus_mainbus_attach(device_t, device_t, void *);
 
@@ -93,34 +95,10 @@ ebus_mainbus_attach(device_t parent, dev
 	struct ebus_interrupt_map_mask *immp;
 	int node, nmapmask, error;
 	struct pyro_softc *psc;
-	int i;
+	int i, j;
 
 	sc->sc_dev = self;
-	sc->sc_node = node = ma->ma_node;
-	sc->sc_ign = INTIGN((ma->ma_upaid) << INTMAP_IGN_SHIFT);
-
-	if (CPU_ISSUN4U) {
-		printf(": ign %x", sc->sc_ign);
-		/* XXX */
-		extern struct cfdriver pyro_cd;
-
-		for (i = 0; i < pyro_cd.cd_ndevs; i++) {
-			device_t dt = pyro_cd.cd_devs[i];
-			psc = device_private(dt);
-			if (psc && psc->sc_ign == sc->sc_ign) {
-				sc->sc_bust = psc->sc_bustag;
-				sc->sc_csr = psc->sc_csr;
-				sc->sc_csrh = psc->sc_csrh;
-				break;
-			}
-		}
-
-		if (sc->sc_csr == 0) {
-			printf(": can't find matching host bridge leaf\n");
-			return;
-		}
-	}
-
+	
 	printf("\n");
 
 	sc->sc_memtag = ebus_mainbus_alloc_bus_tag(sc, ma->ma_bustag,
@@ -130,6 +108,8 @@ ebus_mainbus_attach(device_t parent, dev
 	sc->sc_childbustag = sc->sc_memtag;
 	sc->sc_dmatag = ma->ma_dmatag;
 
+	sc->sc_node = node = ma->ma_node;
+	
 	/*
 	 * fill in our softc with information from the prom
 	 */
@@ -158,6 +138,23 @@ ebus_mainbus_attach(device_t parent, dev
 		break;
 	}
 
+	/*
+	 * Ebus interrupts may be connected to any of the PCI Express
+	 * leafs.  Here we add the appropriate IGN to the interrupt
+	 * mappings such that we can use it to distingish between
+	 * interrupts connected to PCIE-A and PCIE-B.
+	 */
+	for (i = 0; i < sc->sc_nintmap; i++) {
+		for (j = 0; j < pyro_cd.cd_ndevs; j++) {
+			device_t dt = pyro_cd.cd_devs[j];
+			psc = device_private(dt);
+			if (psc && psc->sc_node == sc->sc_intmap[i].cnode) {
+				sc->sc_intmap[i].cintr |= psc->sc_ign;
+				break;
+			}
+		}
+	}
+	
 	error = prom_getprop(node, "ranges", sizeof(struct ebus_mainbus_ranges),
 	    &sc->sc_nrange, (void **)&sc->sc_range);
 	if (error)
@@ -275,7 +272,6 @@ static void *
 ebus_mainbus_intr_establish(bus_space_tag_t t, int ihandle, int level,
 	int (*handler)(void *), void *arg, void (*fastvec)(void) /* ignored */)
 {
-	struct ebus_softc *sc = t->cookie;
 	struct intrhand *ih = NULL;
 	volatile u_int64_t *intrmapptr = NULL, *intrclrptr = NULL;
 	u_int64_t *imap, *iclr;
@@ -334,12 +330,24 @@ XXX
 	}
 #endif
 #endif
-	ihandle |= sc->sc_ign;
+
 	ino = INTINO(ihandle);
 
-	/* XXX */
-	imap = (uint64_t *)((uintptr_t)bus_space_vaddr(sc->sc_bustag, sc->sc_csrh) + 0x1000);
-	iclr = (uint64_t *)((uintptr_t)bus_space_vaddr(sc->sc_bustag, sc->sc_csrh) + 0x1400);
+	struct pyro_softc *psc = NULL;
+	int i;
+
+	for (i = 0; i < pyro_cd.cd_ndevs; i++) {
+		device_t dt = pyro_cd.cd_devs[i];
+		psc = device_private(dt);
+		if (psc && psc->sc_ign == INTIGN(ihandle)) {
+			break;
+		}
+	}
+	if (psc == NULL)
+		return (NULL);
+	
+	imap = (uint64_t *)((uintptr_t)bus_space_vaddr(psc->sc_bustag, psc->sc_csrh) + 0x1000);
+	iclr = (uint64_t *)((uintptr_t)bus_space_vaddr(psc->sc_bustag, psc->sc_csrh) + 0x1400);
 	intrmapptr = &imap[ino];
 	intrclrptr = &iclr[ino];
 	ino |= INTVEC(ihandle);

Index: src/sys/arch/sparc64/dev/ebusvar.h
diff -u src/sys/arch/sparc64/dev/ebusvar.h:1.11 src/sys/arch/sparc64/dev/ebusvar.h:1.12
--- src/sys/arch/sparc64/dev/ebusvar.h:1.11	Fri Jul  1 18:48:36 2011
+++ src/sys/arch/sparc64/dev/ebusvar.h	Sun Aug 24 19:06:14 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ebusvar.h,v 1.11 2011/07/01 18:48:36 dyoung Exp $	*/
+/*	$NetBSD: ebusvar.h,v 1.12 2014/08/24 19:06:14 palle Exp $	*/
 
 /*
  * Copyright (c) 1999, 2000, 2001 Matthew R. Green
@@ -61,12 +61,6 @@ struct ebus_softc {
 
 	int				sc_nrange;	/* counters */
 	int				sc_nintmap;
-
-	int				sc_ign;
-
-	bus_space_tag_t			sc_bust;
-	bus_addr_t			sc_csr;
-	bus_space_handle_t		sc_csrh;
 };
 
 int	ebus_setup_attach_args(struct ebus_softc *, int,

Reply via email to