From owner-svn-src-projects@FreeBSD.ORG Mon Jan 26 21:40:57 2015 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 15D22D0E; Mon, 26 Jan 2015 21:40:57 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 014E923F; Mon, 26 Jan 2015 21:40:57 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t0QLeuOR085597; Mon, 26 Jan 2015 21:40:56 GMT (envelope-from nwhitehorn@FreeBSD.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t0QLeu8H085596; Mon, 26 Jan 2015 21:40:56 GMT (envelope-from nwhitehorn@FreeBSD.org) Message-Id: <201501262140.t0QLeu8H085596@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: nwhitehorn set sender to nwhitehorn@FreeBSD.org using -f From: Nathan Whitehorn Date: Mon, 26 Jan 2015 21:40:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r277777 - projects/powernv/powerpc/pseries X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Jan 2015 21:40:57 -0000 Author: nwhitehorn Date: Mon Jan 26 21:40:56 2015 New Revision: 277777 URL: https://svnweb.freebsd.org/changeset/base/277777 Log: Provide support for multi-socket systems with multiple root interrupt controllers when running outside of a hypervisor. Modified: projects/powernv/powerpc/pseries/xics.c Modified: projects/powernv/powerpc/pseries/xics.c ============================================================================== --- projects/powernv/powerpc/pseries/xics.c Mon Jan 26 21:24:04 2015 (r277776) +++ projects/powernv/powerpc/pseries/xics.c Mon Jan 26 21:40:56 2015 (r277777) @@ -82,7 +82,7 @@ static device_method_t xicp_methods[] = DEVMETHOD(pic_mask, xicp_mask), DEVMETHOD(pic_unmask, xicp_unmask), - { 0, 0 }, + DEVMETHOD_END }; static device_method_t xics_methods[] = { @@ -90,13 +90,15 @@ static device_method_t xics_methods[] = DEVMETHOD(device_probe, xics_probe), DEVMETHOD(device_attach, xics_attach), - { 0, 0 }, + DEVMETHOD_END }; struct xicp_softc { struct mtx sc_mtx; struct resource *mem[MAXCPU]; + int cpu_range[2]; + int ibm_int_on; int ibm_int_off; int ibm_get_xive; @@ -131,6 +133,22 @@ EARLY_DRIVER_MODULE(xicp, ofwbus, xicp_d EARLY_DRIVER_MODULE(xics, ofwbus, xics_driver, xics_devclass, 0, 0, BUS_PASS_INTERRUPT); +static struct resource * +xicp_mem_for_cpu(int cpu) +{ + device_t dev; + struct xicp_softc *sc; + int i; + + for (i = 0; (dev = devclass_get_device(xicp_devclass, i)) != NULL; i++){ + sc = device_get_softc(dev); + if (cpu >= sc->cpu_range[0] && cpu < sc->cpu_range[1]) + return (sc->mem[cpu - sc->cpu_range[0]]); + } + + return (NULL); +} + static int xicp_probe(device_t dev) { @@ -178,8 +196,18 @@ xicp_attach(device_t dev) return (ENXIO); } + if (OF_hasprop(phandle, "ibm,interrupt-server-ranges")) { + OF_getencprop(phandle, "ibm,interrupt-server-ranges", + sc->cpu_range, sizeof(sc->cpu_range)); + device_printf(dev, "Handling CPUs %d-%d\n", sc->cpu_range[0], + sc->cpu_range[1]-1); + } else { + sc->cpu_range[0] = 0; + sc->cpu_range[1] = mp_ncpus; + } + if (mfmsr() & PSL_HV) { - for (i = 0; i < mp_ncpus; i++) { + for (i = 0; i < sc->cpu_range[1] - sc->cpu_range[0]; i++) { sc->mem[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i, RF_ACTIVE); if (sc->mem[i] == NULL) { @@ -254,13 +282,20 @@ static void xicp_dispatch(device_t dev, struct trapframe *tf) { struct xicp_softc *sc; + struct resource *regs = NULL; uint64_t xirr, junk; int i; + if (sc->mem[0]) + regs = xicp_mem_for_cpu(PCPU_GET(cpuid)); + + KASSERT(sc->mem[0] == NULL || regs != NULL, + ("Can't find regs for CPU %d", PCPU_GET(cpuid))); + sc = device_get_softc(dev); for (;;) { - if (sc->mem[0]) { - xirr = bus_read_4(sc->mem[PCPU_GET(cpuid)], 4); + if (regs) { + xirr = bus_read_4(regs, 4); } else { /* Return value in R4, use the PFT call */ phyp_pft_hcall(H_XIRR, 0, 0, 0, 0, &xirr, &junk, &junk); @@ -268,8 +303,8 @@ xicp_dispatch(device_t dev, struct trapf xirr &= 0x00ffffff; if (xirr == 0) { /* No more pending interrupts? */ - if (sc->mem[0]) - bus_write_1(sc->mem[PCPU_GET(cpuid)], 4, 0xff); + if (regs) + bus_write_1(regs, 4, 0xff); else phyp_hcall(H_CPPR, (uint64_t)0xff); break; @@ -278,8 +313,8 @@ xicp_dispatch(device_t dev, struct trapf xirr = MAX_XICP_IRQS; /* Map to FreeBSD magic */ /* Clear IPI */ - if (sc->mem[0]) - bus_write_1(sc->mem[PCPU_GET(cpuid)], 12, 0xff); + if (regs) + bus_write_1(regs, 12, 0xff); else phyp_hcall(H_IPI, (uint64_t)(PCPU_GET(cpuid)), 0xff); @@ -343,7 +378,7 @@ xicp_eoi(device_t dev, u_int irq) xirr = irq | (XICP_PRIORITY << 24); if (sc->mem[0]) - bus_write_4(sc->mem[PCPU_GET(cpuid)], 4, xirr); + bus_write_4(xicp_mem_for_cpu(PCPU_GET(cpuid)), 4, xirr); else phyp_hcall(H_EOI, xirr); } @@ -354,7 +389,7 @@ xicp_ipi(device_t dev, u_int cpu) struct xicp_softc *sc = device_get_softc(dev); if (sc->mem[0]) - bus_write_1(sc->mem[cpu], 12, XICP_PRIORITY); + bus_write_1(xicp_mem_for_cpu(cpu), 12, XICP_PRIORITY); else phyp_hcall(H_IPI, (uint64_t)cpu, XICP_PRIORITY); }