svn commit: r277671 - projects/powernv/powerpc/pseries

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sun Jan 25 02:47:36 UTC 2015


Author: nwhitehorn
Date: Sun Jan 25 02:47:35 2015
New Revision: 277671
URL: https://svnweb.freebsd.org/changeset/base/277671

Log:
  Add SMP support to non-virtualized XICP driver. Note that this does not
  yet support multi-socket systems, which have multiple root PICs.

Modified:
  projects/powernv/powerpc/pseries/xics.c

Modified: projects/powernv/powerpc/pseries/xics.c
==============================================================================
--- projects/powernv/powerpc/pseries/xics.c	Sun Jan 25 02:30:44 2015	(r277670)
+++ projects/powernv/powerpc/pseries/xics.c	Sun Jan 25 02:47:35 2015	(r277671)
@@ -95,8 +95,7 @@ static device_method_t  xics_methods[] =
 
 struct xicp_softc {
 	struct mtx sc_mtx;
-	struct resource *mem;
-	int memrid;
+	struct resource *mem[MAXCPU];
 
 	int ibm_int_on;
 	int ibm_int_off;
@@ -165,6 +164,7 @@ xicp_attach(device_t dev)
 {
 	struct xicp_softc *sc = device_get_softc(dev);
 	phandle_t phandle = ofw_bus_get_node(dev);
+	int i = 0;
 
 	if (rtas_exists()) {
 		sc->ibm_int_on = rtas_token_lookup("ibm,int-on");
@@ -179,12 +179,18 @@ xicp_attach(device_t dev)
 	}
 
 	if (mfmsr() & PSL_HV) {
-		sc->memrid = 0;
-		sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
-		    &sc->memrid, RF_ACTIVE);
-		if (sc->mem == NULL) {
-			device_printf(dev, "Could not alloc mem resource\n");
-			return (ENXIO);
+		for (i = 0; i < mp_ncpus; i++) {
+			sc->mem[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+			    &i, RF_ACTIVE);
+			if (sc->mem[i] == NULL) {
+				device_printf(dev, "Could not alloc mem "
+				    "resource %d\n", i);
+				return (ENXIO);
+			}
+
+			/* Unmask interrupts on all cores */
+			bus_write_1(sc->mem[i], 4, 0xff);
+			bus_write_1(sc->mem[i], 12, 0xff);
 		}
 	}
 
@@ -253,8 +259,8 @@ xicp_dispatch(device_t dev, struct trapf
 
 	sc = device_get_softc(dev);
 	for (;;) {
-		if (sc->mem) {
-			xirr = bus_read_4(sc->mem, 4);
+		if (sc->mem[0]) {
+			xirr = bus_read_4(sc->mem[PCPU_GET(cpuid)], 4);
 		} else {
 			/* Return value in R4, use the PFT call */
 			phyp_pft_hcall(H_XIRR, 0, 0, 0, 0, &xirr, &junk, &junk);
@@ -262,8 +268,8 @@ xicp_dispatch(device_t dev, struct trapf
 		xirr &= 0x00ffffff;
 
 		if (xirr == 0) { /* No more pending interrupts? */
-			if (sc->mem)
-				bus_write_1(sc->mem, 4, 0xff);
+			if (sc->mem[0])
+				bus_write_1(sc->mem[PCPU_GET(cpuid)], 4, 0xff);
 			else
 				phyp_hcall(H_CPPR, (uint64_t)0xff);
 			break;
@@ -272,8 +278,8 @@ xicp_dispatch(device_t dev, struct trapf
 			xirr = MAX_XICP_IRQS;	/* Map to FreeBSD magic */
 
 			/* Clear IPI */
-			if (sc->mem)
-				bus_write_1(sc->mem, 12, 0xff);
+			if (sc->mem[0])
+				bus_write_1(sc->mem[PCPU_GET(cpuid)], 12, 0xff);
 			else
 				phyp_hcall(H_IPI, (uint64_t)(PCPU_GET(cpuid)),
 				    0xff);
@@ -336,8 +342,8 @@ xicp_eoi(device_t dev, u_int irq)
 		irq = XICP_IPI;
 	xirr = irq | (XICP_PRIORITY << 24);
 
-	if (sc->mem)
-		bus_write_4(sc->mem, 4, xirr);
+	if (sc->mem[0])
+		bus_write_4(sc->mem[PCPU_GET(cpuid)], 4, xirr);
 	else
 		phyp_hcall(H_EOI, xirr);
 }
@@ -347,8 +353,8 @@ xicp_ipi(device_t dev, u_int cpu)
 {
 	struct xicp_softc *sc = device_get_softc(dev);
 
-	if (sc->mem)
-		bus_write_1(sc->mem, 12, XICP_PRIORITY); /* Pick node! */
+	if (sc->mem[0])
+		bus_write_1(sc->mem[cpu], 12, XICP_PRIORITY);
 	else
 		phyp_hcall(H_IPI, (uint64_t)cpu, XICP_PRIORITY);
 }


More information about the svn-src-projects mailing list