Module Name: src Committed By: martin Date: Thu Jul 30 09:37:37 UTC 2015
Modified Files: src/sys/arch/arm/broadcom [netbsd-7]: bcm2835_intr.c bcm2835_intr.h bcm2835_obio.c bcm2835reg.h src/sys/arch/arm/cortex [netbsd-7]: gic.c src/sys/arch/arm/marvell [netbsd-7]: mvsoc_intr.h src/sys/arch/arm/omap [netbsd-7]: omap4430_intr.h omap5430_intr.h src/sys/arch/arm/pic [netbsd-7]: pic.c picvar.h src/sys/arch/evbarm/rpi [netbsd-7]: rpi_machdep.c Log Message: Pull up following revision(s) (requested by skrll in ticket #890): sys/arch/arm/pic/pic.c: revision 1.27-1.32 sys/arch/arm/omap/omap5430_intr.h: revision 1.3 sys/arch/arm/broadcom/bcm2835_obio.c: revision 1.25 sys/arch/arm/cortex/gic.c: revision 1.18 sys/arch/arm/broadcom/bcm2835reg.h: revision 1.15 sys/arch/evbarm/rpi/rpi_machdep.c: revision 1.61 sys/arch/arm/broadcom/bcm2835_intr.h: revision 1.2 sys/arch/arm/marvell/mvsoc_intr.h: revision 1.5 sys/arch/arm/broadcom/bcm2835_intr.c: revision 1.8-1.10 sys/arch/arm/pic/picvar.h: revision 1.12-1.14 sys/arch/arm/omap/omap4430_intr.h: revision 1.3 Don't clear CI_ASTPENDING in exception return, do it in ast() instead. Add basic support for __HAVE_PREEMPTION. Use atomic ops for ci_astpending if __HAVE_PREEMPTION is defined. Use kpreempt_disable/kpreempt_enable Add __HAVE_PIC_HAVE_PENDING_INTRS and define it if __HAVE_PIC_SET_PRIORITY is undefined (also define in mvsoc_intr.h since their use of the latter is peculiar). This new define controls whether the pending interrupt logic is compiled. The GIC doesn't use pending interrupts since it uses the priority level on the GIC to control delivery of interrupts, thus there can never be a pending interrupt. The kernel shrinks about 4KB with the removal of the pending interupt support, Only if we __HAVE_PIC_PENDING_INTRS do we need the variables to track them. Add #define __HAVE_PIC_PENDING_INTRS for the non-GIC PICs. Add a pic_cpus to the softc which specifies which cpus the pic can send IPIs to. For GIC, initialize pic_cpus to kcpuset_running since it can handle all the cpus. Adapt pic to deal with the BCM2836 interrupts. Move pic_pending_pics, pic_pending_ipls, and pic_blocked_irqs into a structure and make then per-cpu. There is no global interrupt state anymore. Use right kcpuset call. Don't need pic_ipi_sender anymore. Don't send IPIs to ourselves if sending to everyone. RPI2 MP support. Thanks to Matt Thomas for making this possible with his changes to pic.c Use a bit per IPI type in local mailbox 0 registers. Ok matt@ IPIs should be IPL_HIGH according to rmind@ Fix bcm2836mp_pic_{un,}block_irqs to handle timer AND mailbox interrupts if they're both passed. Thanks to nat@ for finding this. Sprinkle some KASSERTs To generate a diff of this commit: cvs rdiff -u -r1.3.12.2 -r1.3.12.3 src/sys/arch/arm/broadcom/bcm2835_intr.c cvs rdiff -u -r1.1 -r1.1.18.1 src/sys/arch/arm/broadcom/bcm2835_intr.h cvs rdiff -u -r1.20.2.2 -r1.20.2.3 src/sys/arch/arm/broadcom/bcm2835_obio.c cvs rdiff -u -r1.10.12.3 -r1.10.12.4 src/sys/arch/arm/broadcom/bcm2835reg.h cvs rdiff -u -r1.10.2.4 -r1.10.2.5 src/sys/arch/arm/cortex/gic.c cvs rdiff -u -r1.4 -r1.4.4.1 src/sys/arch/arm/marvell/mvsoc_intr.h cvs rdiff -u -r1.2 -r1.2.18.1 src/sys/arch/arm/omap/omap4430_intr.h cvs rdiff -u -r1.2 -r1.2.4.1 src/sys/arch/arm/omap/omap5430_intr.h cvs rdiff -u -r1.22.2.2 -r1.22.2.3 src/sys/arch/arm/pic/pic.c cvs rdiff -u -r1.10.2.1 -r1.10.2.2 src/sys/arch/arm/pic/picvar.h cvs rdiff -u -r1.43.2.4 -r1.43.2.5 src/sys/arch/evbarm/rpi/rpi_machdep.c 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/arm/broadcom/bcm2835_intr.c diff -u src/sys/arch/arm/broadcom/bcm2835_intr.c:1.3.12.2 src/sys/arch/arm/broadcom/bcm2835_intr.c:1.3.12.3 --- src/sys/arch/arm/broadcom/bcm2835_intr.c:1.3.12.2 Wed Mar 11 20:22:55 2015 +++ src/sys/arch/arm/broadcom/bcm2835_intr.c Thu Jul 30 09:37:37 2015 @@ -1,7 +1,7 @@ -/* $NetBSD: bcm2835_intr.c,v 1.3.12.2 2015/03/11 20:22:55 snj Exp $ */ +/* $NetBSD: bcm2835_intr.c,v 1.3.12.3 2015/07/30 09:37:37 martin Exp $ */ /*- - * Copyright (c) 2012 The NetBSD Foundation, Inc. + * Copyright (c) 2012, 2015 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bcm2835_intr.c,v 1.3.12.2 2015/03/11 20:22:55 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bcm2835_intr.c,v 1.3.12.3 2015/07/30 09:37:37 martin Exp $"); #define _INTR_PRIVATE @@ -67,21 +67,12 @@ static int bcm2836mp_pic_find_pending_ir static void bcm2836mp_pic_establish_irq(struct pic_softc *, struct intrsource *); static void bcm2836mp_pic_source_name(struct pic_softc *, int, char *, size_t); -#if 0 #ifdef MULTIPROCESSOR int bcm2836mp_ipi_handler(void *); static void bcm2836mp_cpu_init(struct pic_softc *, struct cpu_info *); static void bcm2836mp_send_ipi(struct pic_softc *, const kcpuset_t *, u_long); #endif #endif -#endif - -#ifdef MULTIPROCESSOR -static void -bcm2835_dummy(struct pic_softc *pic, const kcpuset_t *kcp, u_long ipi) -{ -} -#endif static int bcm2835_icu_match(device_t, cfdata_t, void *); static void bcm2835_icu_attach(device_t, device_t, void *); @@ -92,9 +83,6 @@ static struct pic_ops bcm2835_picops = { .pic_find_pending_irqs = bcm2835_pic_find_pending_irqs, .pic_establish_irq = bcm2835_pic_establish_irq, .pic_source_name = bcm2835_pic_source_name, -#if defined(MULTIPROCESSOR) - .pic_ipi_send = bcm2835_dummy, -#endif }; struct pic_softc bcm2835_pic = { @@ -110,16 +98,33 @@ static struct pic_ops bcm2836mp_picops = .pic_find_pending_irqs = bcm2836mp_pic_find_pending_irqs, .pic_establish_irq = bcm2836mp_pic_establish_irq, .pic_source_name = bcm2836mp_pic_source_name, -#if 0 && defined(MULTIPROCESSOR) +#if defined(MULTIPROCESSOR) .pic_cpu_init = bcm2836mp_cpu_init, .pic_ipi_send = bcm2836mp_send_ipi, #endif }; -struct pic_softc bcm2836mp_pic = { - .pic_ops = &bcm2836mp_picops, - .pic_maxsources = BCM2836MP_NIRQ, - .pic_name = "bcm2836 mp pic", +struct pic_softc bcm2836mp_pic[BCM2836_NCPUS] = { + [0] = { + .pic_ops = &bcm2836mp_picops, + .pic_maxsources = BCM2836_NIRQPERCPU, + .pic_name = "bcm2836 pic", + }, + [1] = { + .pic_ops = &bcm2836mp_picops, + .pic_maxsources = BCM2836_NIRQPERCPU, + .pic_name = "bcm2836 pic", + }, + [2] = { + .pic_ops = &bcm2836mp_picops, + .pic_maxsources = BCM2836_NIRQPERCPU, + .pic_name = "bcm2836 pic", + }, + [3] = { + .pic_ops = &bcm2836mp_picops, + .pic_maxsources = BCM2836_NIRQPERCPU, + .pic_name = "bcm2836 pic", + }, }; #endif @@ -165,7 +170,7 @@ static const char * const bcm2835_source }; #if defined(BCM2836) -static const char * const bcm2836mp_sources[BCM2836MP_NIRQ] = { +static const char * const bcm2836mp_sources[BCM2836_NIRQPERCPU] = { "cntpsirq", "cntpnsirq", "cnthpirq", "cntvirq", "mailbox0", "mailbox1", "mailbox2", "mailbox3", }; @@ -211,14 +216,14 @@ bcm2835_icu_attach(device_t parent, devi bcmicu_sc = sc; - pic_add(sc->sc_pic, 0); - #if defined(BCM2836) -#if 0 && defined(MULTIPROCESSOR) +#if defined(MULTIPROCESSOR) aprint_normal(": Multiprocessor"); #endif - pic_add(&bcm2836mp_pic, BCM2836_INT_LOCALBASE); + + bcm2836mp_intr_init(curcpu()); #endif + pic_add(sc->sc_pic, BCM2835_INT_BASE); aprint_normal("\n"); } @@ -228,15 +233,18 @@ bcm2835_irq_handler(void *frame) { struct cpu_info * const ci = curcpu(); const int oldipl = ci->ci_cpl; + const cpuid_t cpuid = ci->ci_cpuid; const uint32_t oldipl_mask = __BIT(oldipl); int ipl_mask = 0; ci->ci_data.cpu_nintr++; bcm2835_barrier(); - ipl_mask = bcm2835_pic_find_pending_irqs(&bcm2835_pic); + if (cpuid == 0) { + ipl_mask = bcm2835_pic_find_pending_irqs(&bcm2835_pic); + } #if defined(BCM2836) - ipl_mask |= bcm2836mp_pic_find_pending_irqs(&bcm2836mp_pic); + ipl_mask |= bcm2836mp_pic_find_pending_irqs(&bcm2836mp_pic[cpuid]); #endif /* @@ -283,8 +291,8 @@ bcm2835_pic_find_pending_irqs(struct pic gpu1irq = bpending & BCM2835_INTBIT_GPU1; if (armirq) { - ipl |= pic_mark_pending_sources(pic, BCM2835_INT_BASICBASE, - armirq); + ipl |= pic_mark_pending_sources(pic, + BCM2835_INT_BASICBASE - BCM2835_INT_BASE, armirq); } @@ -292,15 +300,15 @@ bcm2835_pic_find_pending_irqs(struct pic uint32_t pending1; pending1 = read_bcm2835reg(BCM2835_INTC_IRQ1PENDING); - ipl |= pic_mark_pending_sources(pic, BCM2835_INT_GPU0BASE, - pending1); + ipl |= pic_mark_pending_sources(pic, + BCM2835_INT_GPU0BASE - BCM2835_INT_BASE, pending1); } if (gpu1irq || (bpending & BCM2835_INTBIT_PENDING2)) { uint32_t pending2; pending2 = read_bcm2835reg(BCM2835_INTC_IRQ2PENDING); - ipl |= pic_mark_pending_sources(pic, BCM2835_INT_GPU1BASE, - pending2); + ipl |= pic_mark_pending_sources(pic, + BCM2835_INT_GPU1BASE - BCM2835_INT_BASE, pending2); } return ipl; @@ -329,15 +337,17 @@ bcm2835_pic_source_name(struct pic_softc #define BCM2836MP_MAILBOX_IRQS __BITS(4,4) #define BCM2836MP_ALL_IRQS \ - (BCM2836MP_TIMER_IRQS | BCM2836MP_MAILBOX_IRQS) + (BCM2836MP_TIMER_IRQS | BCM2836MP_MAILBOX_IRQS) static void bcm2836mp_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask) { - const int cpuid = 0; + struct cpu_info * const ci = curcpu(); + const cpuid_t cpuid = ci->ci_cpuid; -//printf("%s: irqbase %zu irq_mask %08x\n", __func__, irqbase, irq_mask); + KASSERT(pic == &bcm2836mp_pic[cpuid]); + KASSERT(irqbase == 0); if (irq_mask & BCM2836MP_TIMER_IRQS) { uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_TIMER_IRQS); @@ -351,8 +361,8 @@ bcm2836mp_pic_unblock_irqs(struct pic_so BCM2836_LOCAL_TIMER_IRQ_CONTROL_BASE, BCM2836_LOCAL_TIMER_IRQ_CONTROL_SIZE, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE); -//printf("%s: val %08x\n", __func__, val); - } else if (irq_mask & BCM2836MP_MAILBOX_IRQS) { + } + if (irq_mask & BCM2836MP_MAILBOX_IRQS) { uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_MAILBOX_IRQS); uint32_t val = bus_space_read_4(al_iot, al_ioh, BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid)); @@ -373,9 +383,12 @@ static void bcm2836mp_pic_block_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask) { - const int cpuid = 0; + struct cpu_info * const ci = curcpu(); + const cpuid_t cpuid = ci->ci_cpuid; + + KASSERT(pic == &bcm2836mp_pic[cpuid]); + KASSERT(irqbase == 0); -//printf("%s: irqbase %zu irq_mask %08x\n", __func__, irqbase, irq_mask); if (irq_mask & BCM2836MP_TIMER_IRQS) { uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_TIMER_IRQS); uint32_t val = bus_space_read_4(al_iot, al_ioh, @@ -384,8 +397,8 @@ bcm2836mp_pic_block_irqs(struct pic_soft bus_space_write_4(al_iot, al_ioh, BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid), val); -//printf("%s: val %08x\n", __func__, val); - } else if (irq_mask & BCM2836MP_MAILBOX_IRQS) { + } + if (irq_mask & BCM2836MP_MAILBOX_IRQS) { uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_MAILBOX_IRQS); uint32_t val = bus_space_read_4(al_iot, al_ioh, BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid)); @@ -399,14 +412,16 @@ bcm2836mp_pic_block_irqs(struct pic_soft return; } - static int bcm2836mp_pic_find_pending_irqs(struct pic_softc *pic) { - const int cpuid = 0; + struct cpu_info * const ci = curcpu(); + const cpuid_t cpuid = ci->ci_cpuid; uint32_t lpending; int ipl = 0; + KASSERT(pic == &bcm2836mp_pic[cpuid]); + bcm2835_barrier(); lpending = bus_space_read_4(al_iot, al_ioh, @@ -424,19 +439,106 @@ bcm2836mp_pic_find_pending_irqs(struct p static void bcm2836mp_pic_establish_irq(struct pic_softc *pic, struct intrsource *is) { - /* Nothing really*/ KASSERT(is->is_irq >= 0); - KASSERT(is->is_irq < BCM2836MP_NIRQ); -// KASSERT(is->is_type == IST_LEVEL); - - + KASSERT(is->is_irq < BCM2836_NIRQPERCPU); } static void bcm2836mp_pic_source_name(struct pic_softc *pic, int irq, char *buf, size_t len) { - irq %= 32; + + irq %= BCM2836_NIRQPERCPU; strlcpy(buf, bcm2836mp_sources[irq], len); } + + +#ifdef MULTIPROCESSOR +static void bcm2836mp_cpu_init(struct pic_softc *pic, struct cpu_info *ci) +{ + + /* Enable IRQ and not FIQ */ + bus_space_write_4(al_iot, al_ioh, + BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(ci->ci_cpuid), 1); +} + + +static void +bcm2836mp_send_ipi(struct pic_softc *pic, const kcpuset_t *kcp, u_long ipi) +{ + KASSERT(pic != NULL); + KASSERT(pic != &bcm2835_pic); + KASSERT(pic->pic_cpus != NULL); + + const cpuid_t cpuid = pic - &bcm2836mp_pic[0]; + + bus_space_write_4(al_iot, al_ioh, + BCM2836_LOCAL_MAILBOX0_SETN(cpuid), __BIT(ipi)); +} + +int +bcm2836mp_ipi_handler(void *priv) +{ + const struct cpu_info *ci = curcpu(); + const cpuid_t cpuid = ci->ci_cpuid; + uint32_t ipimask, bit; + + ipimask = bus_space_read_4(al_iot, al_ioh, + BCM2836_LOCAL_MAILBOX0_CLRN(cpuid)); + bus_space_write_4(al_iot, al_ioh, BCM2836_LOCAL_MAILBOX0_CLRN(cpuid), + ipimask); + + while ((bit = ffs(ipimask)) > 0) { + const u_int ipi = bit - 1; + switch (ipi) { + case IPI_AST: + case IPI_NOP: +#ifdef __HAVE_PREEMPTION + case IPI_KPREEMPT: +#endif + pic_ipi_nop(priv); + break; + case IPI_XCALL: + pic_ipi_xcall(priv); + break; + case IPI_GENERIC: + pic_ipi_generic(priv); + break; + case IPI_SHOOTDOWN: + pic_ipi_shootdown(priv); + break; +#ifdef DDB + case IPI_DDB: + pic_ipi_ddb(priv); + break; +#endif + } + ipimask &= ~__BIT(ipi); + } + + return 1; +} + +void +bcm2836mp_intr_init(struct cpu_info *ci) +{ + const cpuid_t cpuid = ci->ci_cpuid; + struct pic_softc * const pic = &bcm2836mp_pic[cpuid]; + + pic->pic_cpus = ci->ci_kcpuset; + pic_add(pic, BCM2836_INT_BASECPUN(cpuid)); + + intr_establish(BCM2836_INT_MAILBOX0_CPUN(cpuid), IPL_HIGH, + IST_LEVEL | IST_MPSAFE, bcm2836mp_ipi_handler, NULL); + + /* clock interrupt will attach with gtmr */ + if (cpuid == 0) + return; + + intr_establish(BCM2836_INT_CNTVIRQ_CPUN(cpuid), IPL_CLOCK, + IST_LEVEL | IST_MPSAFE, gtmr_intr, NULL); + +} +#endif + #endif Index: src/sys/arch/arm/broadcom/bcm2835_intr.h diff -u src/sys/arch/arm/broadcom/bcm2835_intr.h:1.1 src/sys/arch/arm/broadcom/bcm2835_intr.h:1.1.18.1 --- src/sys/arch/arm/broadcom/bcm2835_intr.h:1.1 Thu Jul 26 06:21:57 2012 +++ src/sys/arch/arm/broadcom/bcm2835_intr.h Thu Jul 30 09:37:37 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm2835_intr.h,v 1.1 2012/07/26 06:21:57 skrll Exp $ */ +/* $NetBSD: bcm2835_intr.h,v 1.1.18.1 2015/07/30 09:37:37 martin Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -38,8 +38,8 @@ void bcm2835_irq_handler(void *); -#define PIC_MAXSOURCES 96 -#define PIC_MAXMAXSOURCES 128 +#define PIC_MAXSOURCES 96 + (4*32) +#define PIC_MAXMAXSOURCES 96 + (4*32) + 32 #include <arm/pic/picvar.h> @@ -50,6 +50,8 @@ bcm2835_intr_establish(int irq, int ipl, return intr_establish(irq, ipl, IST_LEVEL, func, arg); } +void bcm2836mp_intr_init(struct cpu_info *); + #endif /* _LOCORE */ #endif /* _BCM2835_INTR_H_ */ Index: src/sys/arch/arm/broadcom/bcm2835_obio.c diff -u src/sys/arch/arm/broadcom/bcm2835_obio.c:1.20.2.2 src/sys/arch/arm/broadcom/bcm2835_obio.c:1.20.2.3 --- src/sys/arch/arm/broadcom/bcm2835_obio.c:1.20.2.2 Wed Mar 11 20:22:55 2015 +++ src/sys/arch/arm/broadcom/bcm2835_obio.c Thu Jul 30 09:37:37 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm2835_obio.c,v 1.20.2.2 2015/03/11 20:22:55 snj Exp $ */ +/* $NetBSD: bcm2835_obio.c,v 1.20.2.3 2015/07/30 09:37:37 martin Exp $ */ /*- * Copyright (c) 2012, 2014 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bcm2835_obio.c,v 1.20.2.2 2015/03/11 20:22:55 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bcm2835_obio.c,v 1.20.2.3 2015/07/30 09:37:37 martin Exp $"); #include "locators.h" #include "obio.h" @@ -38,10 +38,10 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_obio #include "opt_bcm283x.h" #include <sys/param.h> -#include <sys/systm.h> -#include <sys/device.h> - #include <sys/bus.h> +#include <sys/cpu.h> +#include <sys/device.h> +#include <sys/systm.h> #include <arm/broadcom/bcm2835reg.h> #include <arm/broadcom/bcm2835var.h> @@ -262,7 +262,6 @@ obio_attach(device_t parent, device_t se .mpcaa_irq = ad->ad_intr, }; - config_found(self, &mpcaa, NULL); continue; } @@ -314,5 +313,9 @@ obio_print(void *aux, const char *name) void bcm2836_cpu_hatch(struct cpu_info *ci) { + + bcm2836mp_intr_init(ci); + + gtmr_init_cpu_clock(ci); } #endif Index: src/sys/arch/arm/broadcom/bcm2835reg.h diff -u src/sys/arch/arm/broadcom/bcm2835reg.h:1.10.12.3 src/sys/arch/arm/broadcom/bcm2835reg.h:1.10.12.4 --- src/sys/arch/arm/broadcom/bcm2835reg.h:1.10.12.3 Wed Mar 11 20:22:55 2015 +++ src/sys/arch/arm/broadcom/bcm2835reg.h Thu Jul 30 09:37:37 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm2835reg.h,v 1.10.12.3 2015/03/11 20:22:55 snj Exp $ */ +/* $NetBSD: bcm2835reg.h,v 1.10.12.4 2015/07/30 09:37:37 martin Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -83,7 +83,7 @@ #define BCM2835_USB_SIZE 0x20000 #define BCM2835_DMA15_SIZE 0x100 -#define BCM2835_IOPHYSTOVIRT(a) \ +#define BCM2835_IOPHYSTOVIRT(a) \ ((0xf0000000 | (((a) & 0xf0000000) >> 4)) + ((a) & ~0xff000000)) #define BCM2835_BUSADDR_CACHE_MASK 0xc0000000 @@ -127,8 +127,40 @@ #define BCM2835_INTC_ENABLEBASE (BCM2835_INTC_BASE + 0x10) #define BCM2835_INTC_DISABLEBASE (BCM2835_INTC_BASE + 0x1c) -/* Interrupt source */ -#define BCM2835_INT_GPU0BASE 0 +#if defined(BCM2836) +#define BCM2836_NCPUS 4 +#define BCM2836_NIRQPERCPU 32 + +#define BCM2836_INT_LOCALBASE 0 +#define BCM2836_INT_BASECPUN(n) (BCM2836_INT_LOCALBASE + ((n) * BCM2836_NIRQPERCPU)) +#define BCM2836_NIRQ (BCM2836_NIRQPERCPU * BCM2836_NCPUS) + +#define BCM2835_INT_BASE BCM2836_NIRQ + +#define BCM2836_INT_CNTPSIRQ 0 +#define BCM2836_INT_CNTPNSIRQ 1 +#define BCM2836_INT_CNTHPIRQ 2 +#define BCM2836_INT_CNTVIRQ 3 +#define BCM2836_INT_MAILBOX0 4 +#define BCM2836_INT_MAILBOX1 5 +#define BCM2836_INT_MAILBOX2 6 +#define BCM2836_INT_MAILBOX3 7 +#define BCM2836_INT_GPU_FAST 8 +#define BCM2836_INT_PMU_FAST 9 +#define BCM2836_INT_ZERO 10 +#define BCM2836_INT_TIMER 11 +#define BCM2836_INT_NLOCAL 12 + +#define BCM2836_INT_CNTVIRQ_CPUN(n) (BCM2836_INT_BASECPUN(n) + BCM2836_INT_CNTVIRQ) +#define BCM2836_INT_MAILBOX0_CPUN(n) (BCM2836_INT_BASECPUN(n) + BCM2836_INT_MAILBOX0) +#else +#define BCM2835_INT_BASE 0 +#endif /* !BCM2836 */ + +/* Periperal Interrupt sources */ +#define BCM2835_NIRQ 96 + +#define BCM2835_INT_GPU0BASE (BCM2835_INT_BASE + 0) #define BCM2835_INT_TIMER0 (BCM2835_INT_GPU0BASE + 0) #define BCM2835_INT_TIMER1 (BCM2835_INT_GPU0BASE + 1) #define BCM2835_INT_TIMER2 (BCM2835_INT_GPU0BASE + 2) @@ -140,7 +172,7 @@ #define BCM2835_INT_AUX (BCM2835_INT_GPU0BASE + 29) #define BCM2835_INT_ARM (BCM2835_INT_GPU0BASE + 30) -#define BCM2835_INT_GPU1BASE 32 +#define BCM2835_INT_GPU1BASE (BCM2835_INT_BASE + 32) #define BCM2835_INT_GPIO0 (BCM2835_INT_GPU1BASE + 17) #define BCM2835_INT_GPIO1 (BCM2835_INT_GPU1BASE + 18) #define BCM2835_INT_GPIO2 (BCM2835_INT_GPU1BASE + 19) @@ -151,7 +183,7 @@ #define BCM2835_INT_UART0 (BCM2835_INT_GPU1BASE + 25) #define BCM2835_INT_EMMC (BCM2835_INT_GPU1BASE + 30) -#define BCM2835_INT_BASICBASE 64 +#define BCM2835_INT_BASICBASE (BCM2835_INT_BASE + 64) #define BCM2835_INT_ARMTIMER (BCM2835_INT_BASICBASE + 0) #define BCM2835_INT_ARMMAILBOX (BCM2835_INT_BASICBASE + 1) #define BCM2835_INT_ARMDOORBELL0 (BCM2835_INT_BASICBASE + 2) @@ -161,31 +193,8 @@ #define BCM2835_INT_ILLEGALTYPE0 (BCM2835_INT_BASICBASE + 6) #define BCM2835_INT_ILLEGALTYPE1 (BCM2835_INT_BASICBASE + 7) -#define BCM2836_NCPUS 4 - -#define BCM2836_INT_LOCALBASE 96 - -#define BCM2836_INT_CNTPSIRQ 0 -#define BCM2836_INT_CNTPNSIRQ 1 -#define BCM2836_INT_CNTHPIRQ 2 -#define BCM2836_INT_CNTVIRQ 3 -#define BCM2836_INT_MAILBOX0 4 -#define BCM2836_INT_MAILBOX1 5 -#define BCM2836_INT_MAILBOX2 6 -#define BCM2836_INT_MAILBOX3 7 -#define BCM2836_INT_GPU_FAST 8 -#define BCM2836_INT_PMU_FAST 9 -#define BCM2836_INT_ZERO 10 -#define BCM2836_INT_TIMER 11 -#define BCM2836_INT_NLOCAL 12 - -#define BCM2836_INT_CNTVIRQ_CPUN(n) (BCM2836_INT_LOCALBASE + ((n) * 32) + BCM2836_INT_CNTVIRQ) -#define BCM2836_INT_MAILBOX0_CPUN(n) (BCM2836_INT_LOCALBASE + ((n) * 32) + BCM2836_INT_MAILBOX0) - -#define BCM2835_NIRQ 96 -#define BCM2836MP_NIRQ 32 -#define BCM2835_UART0_CLK 3000000 +#define BCM2835_UART0_CLK 3000000 #define BCM2836_ARM_LOCAL_VBASE \ BCM2835_IOPHYSTOVIRT(BCM2836_ARM_LOCAL_BASE) Index: src/sys/arch/arm/cortex/gic.c diff -u src/sys/arch/arm/cortex/gic.c:1.10.2.4 src/sys/arch/arm/cortex/gic.c:1.10.2.5 --- src/sys/arch/arm/cortex/gic.c:1.10.2.4 Sat Mar 21 17:24:19 2015 +++ src/sys/arch/arm/cortex/gic.c Thu Jul 30 09:37:37 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: gic.c,v 1.10.2.4 2015/03/21 17:24:19 snj Exp $ */ +/* $NetBSD: gic.c,v 1.10.2.5 2015/07/30 09:37:37 martin Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. * All rights reserved. @@ -34,7 +34,7 @@ #define _INTR_PRIVATE #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.10.2.4 2015/03/21 17:24:19 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.10.2.5 2015/07/30 09:37:37 martin Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -569,6 +569,9 @@ armgic_attach(device_t parent, device_t "%zu sources (%zu valid)\n", sc->sc_pic.pic_maxsources, sc->sc_gic_lines); +#ifdef MULTIPROCESSOR + sc->sc_pic.pic_cpus = kcpuset_running; +#endif pic_add(&sc->sc_pic, 0); /* Index: src/sys/arch/arm/marvell/mvsoc_intr.h diff -u src/sys/arch/arm/marvell/mvsoc_intr.h:1.4 src/sys/arch/arm/marvell/mvsoc_intr.h:1.4.4.1 --- src/sys/arch/arm/marvell/mvsoc_intr.h:1.4 Tue Mar 18 06:46:14 2014 +++ src/sys/arch/arm/marvell/mvsoc_intr.h Thu Jul 30 09:37:37 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsoc_intr.h,v 1.4 2014/03/18 06:46:14 matt Exp $ */ +/* $NetBSD: mvsoc_intr.h,v 1.4.4.1 2015/07/30 09:37:37 martin Exp $ */ /* * Copyright (c) 2010 KIYOHARA Takashi * All rights reserved. @@ -33,6 +33,7 @@ #if defined(ARMADAXP) #define __HAVE_PIC_SET_PRIORITY +#define __HAVE_PIC_PENDING_INTRS #endif #endif Index: src/sys/arch/arm/omap/omap4430_intr.h diff -u src/sys/arch/arm/omap/omap4430_intr.h:1.2 src/sys/arch/arm/omap/omap4430_intr.h:1.2.18.1 --- src/sys/arch/arm/omap/omap4430_intr.h:1.2 Sat Sep 1 00:05:36 2012 +++ src/sys/arch/arm/omap/omap4430_intr.h Thu Jul 30 09:37:37 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: omap4430_intr.h,v 1.2 2012/09/01 00:05:36 matt Exp $ */ +/* $NetBSD: omap4430_intr.h,v 1.2.18.1 2015/07/30 09:37:37 martin Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. * All rights reserved. @@ -44,8 +44,9 @@ #define PIC_MAXMAXSOURCES (PIC_MAXSOURCES+6*32) /* - * The BCM53xx uses a generic interrupt controller so pull that stuff. + * The OMAP4 uses a generic interrupt controller so pull in that stuff. */ +#define __HAVE_PIC_PENDING_INTRS #include <arm/cortex/gic_intr.h> #include <arm/cortex/a9tmr_intr.h> /* A9 Timer PPIs */ Index: src/sys/arch/arm/omap/omap5430_intr.h diff -u src/sys/arch/arm/omap/omap5430_intr.h:1.2 src/sys/arch/arm/omap/omap5430_intr.h:1.2.4.1 --- src/sys/arch/arm/omap/omap5430_intr.h:1.2 Wed Apr 9 19:50:01 2014 +++ src/sys/arch/arm/omap/omap5430_intr.h Thu Jul 30 09:37:37 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: omap5430_intr.h,v 1.2 2014/04/09 19:50:01 matt Exp $ */ +/* $NetBSD: omap5430_intr.h,v 1.2.4.1 2015/07/30 09:37:37 martin Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. * All rights reserved. @@ -40,8 +40,9 @@ #define PIC_MAXMAXSOURCES (PIC_MAXSOURCES+8*32) /* - * The BCM53xx uses a generic interrupt controller so pull that stuff. + * The OMAP5 uses a generic interrupt controller so pull in that stuff. */ +#define __HAVE_PIC_PENDING_INTRS #include <arm/cortex/gic_intr.h> #include <arm/cortex/gtmr_intr.h> /* Generic Timer PPIs */ Index: src/sys/arch/arm/pic/pic.c diff -u src/sys/arch/arm/pic/pic.c:1.22.2.2 src/sys/arch/arm/pic/pic.c:1.22.2.3 --- src/sys/arch/arm/pic/pic.c:1.22.2.2 Mon Nov 10 19:57:26 2014 +++ src/sys/arch/arm/pic/pic.c Thu Jul 30 09:37:37 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: pic.c,v 1.22.2.2 2014/11/10 19:57:26 martin Exp $ */ +/* $NetBSD: pic.c,v 1.22.2.3 2015/07/30 09:37:37 martin Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. * All rights reserved. @@ -33,7 +33,7 @@ #include "opt_multiprocessor.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.22.2.2 2014/11/10 19:57:26 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.22.2.3 2015/07/30 09:37:37 martin Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -54,22 +54,38 @@ __KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.22 #include <arm/pic/picvar.h> +#if defined(__HAVE_PIC_PENDING_INTRS) +/* + * This implementation of pending interrupts on a MULTIPROCESSOR system makes + * the assumption that a PIC (pic_softc) shall only have all its interrupts + * come from the same CPU. In other words, interrupts from a single PIC will + * not be distributed among multiple CPUs. + */ +struct pic_pending { + volatile uint32_t blocked_pics; + volatile uint32_t pending_pics; + volatile uint32_t pending_ipls; +}; static uint32_t pic_find_pending_irqs_by_ipl(struct pic_softc *, size_t, uint32_t, int); static struct pic_softc * - pic_list_find_pic_by_pending_ipl(uint32_t); + pic_list_find_pic_by_pending_ipl(struct pic_pending *, uint32_t); static void - pic_deliver_irqs(struct pic_softc *, int, void *); + pic_deliver_irqs(struct pic_pending *, struct pic_softc *, int, void *); static void - pic_list_deliver_irqs(register_t, int, void *); + pic_list_deliver_irqs(struct pic_pending *, register_t, int, void *); + +#ifdef MULTIPROCESSOR +percpu_t *pic_pending_percpu; +#else +struct pic_pending pic_pending; +#endif /* MULTIPROCESSOR */ +#endif /* __HAVE_PIC_PENDING_INTRS */ struct pic_softc *pic_list[PIC_MAXPICS]; #if PIC_MAXPICS > 32 #error PIC_MAXPICS > 32 not supported #endif -volatile uint32_t pic_blocked_pics; -volatile uint32_t pic_pending_pics; -volatile uint32_t pic_pending_ipls; struct intrsource *pic_sources[PIC_MAXMAXSOURCES]; struct intrsource *pic__iplsources[PIC_MAXMAXSOURCES]; struct intrsource **pic_iplsource[NIPL] = { @@ -139,27 +155,30 @@ intr_cpu_init(struct cpu_info *ci) typedef void (*pic_ipi_send_func_t)(struct pic_softc *, u_long); -static struct pic_softc * -pic_ipi_sender(void) +void +intr_ipi_send(const kcpuset_t *kcp, u_long ipi) { + struct cpu_info * const ci = curcpu(); + KASSERT(ipi < NIPI); + bool __diagused sent_p = false; for (size_t slot = 0; slot < PIC_MAXPICS; slot++) { struct pic_softc * const pic = pic_list[slot]; - if (pic != NULL && pic->pic_ops->pic_ipi_send != NULL) { - return pic; + if (pic == NULL || pic->pic_cpus == NULL) + continue; + if (kcp == NULL || kcpuset_intersecting_p(kcp, pic->pic_cpus)) { + // never send to ourself + if (pic->pic_cpus == ci->ci_kcpuset) + continue; + + (*pic->pic_ops->pic_ipi_send)(pic, kcp, ipi); + // If we were targeting a single CPU or this pic + // handles all cpus, we're done. + if (kcp != NULL || pic->pic_cpus == kcpuset_running) + return; + sent_p = true; } } - return NULL; -} - -void -intr_ipi_send(const kcpuset_t *kcp, u_long ipi) -{ - struct pic_softc * const pic = pic_ipi_sender(); - KASSERT(ipi < NIPI); - if (cold && pic == NULL) - return; - KASSERT(pic != NULL); - (*pic->pic_ops->pic_ipi_send)(pic, kcp, ipi); + KASSERT(cold || sent_p); } #endif /* MULTIPROCESSOR */ @@ -190,6 +209,7 @@ pic_handle_intr(void *arg) return rv > 0; } +#if defined(__HAVE_PIC_PENDING_INTRS) void pic_mark_pending_source(struct pic_softc *pic, struct intrsource *is) { @@ -199,8 +219,16 @@ pic_mark_pending_source(struct pic_softc __BIT(is->is_irq & 0x1f)); atomic_or_32(&pic->pic_pending_ipls, ipl_mask); - atomic_or_32(&pic_pending_ipls, ipl_mask); - atomic_or_32(&pic_pending_pics, __BIT(pic->pic_id)); +#ifdef MULTIPROCESSOR + struct pic_pending *pend = percpu_getref(pic_pending_percpu); +#else + struct pic_pending *pend = &pic_pending; +#endif + atomic_or_32(&pend->pending_ipls, ipl_mask); + atomic_or_32(&pend->pending_pics, __BIT(pic->pic_id)); +#ifdef MULTIPROCESSOR + percpu_putref(pic_pending_percpu); +#endif } void @@ -243,9 +271,16 @@ pic_mark_pending_sources(struct pic_soft } atomic_or_32(&pic->pic_pending_ipls, ipl_mask); - atomic_or_32(&pic_pending_ipls, ipl_mask); - atomic_or_32(&pic_pending_pics, __BIT(pic->pic_id)); - +#ifdef MULTIPROCESSOR + struct pic_pending *pend = percpu_getref(pic_pending_percpu); +#else + struct pic_pending *pend = &pic_pending; +#endif + atomic_or_32(&pend->pending_ipls, ipl_mask); + atomic_or_32(&pend->pending_pics, __BIT(pic->pic_id)); +#ifdef MULTIPROCESSOR + percpu_putref(pic_pending_percpu); +#endif return ipl_mask; } @@ -277,6 +312,7 @@ pic_find_pending_irqs_by_ipl(struct pic_ pending &= ~irq_mask; } } +#endif /* __HAVE_PIC_PENDING_INTRS */ void pic_dispatch(struct intrsource *is, void *frame) @@ -312,8 +348,10 @@ pic_dispatch(struct intrsource *is, void percpu_putref(is->is_pic->pic_percpu); } +#if defined(__HAVE_PIC_PENDING_INTRS) void -pic_deliver_irqs(struct pic_softc *pic, int ipl, void *frame) +pic_deliver_irqs(struct pic_pending *pend, struct pic_softc *pic, int ipl, + void *frame) { const uint32_t ipl_mask = __BIT(ipl); struct intrsource *is; @@ -328,7 +366,7 @@ pic_deliver_irqs(struct pic_softc *pic, uint32_t blocked_irqs; int irq; bool progress __diagused = false; - + KASSERT(pic->pic_pending_ipls & ipl_mask); irq_base = 0; @@ -392,7 +430,7 @@ pic_deliver_irqs(struct pic_softc *pic, } while (pending_irqs); if (blocked_irqs) { atomic_or_32(iblocked, blocked_irqs); - atomic_or_32(&pic_blocked_pics, __BIT(pic->pic_id)); + atomic_or_32(&pend->blocked_pics, __BIT(pic->pic_id)); } } @@ -402,15 +440,16 @@ pic_deliver_irqs(struct pic_softc *pic, * about these. */ if (atomic_and_32_nv(&pic->pic_pending_ipls, ~ipl_mask) == 0) - atomic_and_32(&pic_pending_pics, ~__BIT(pic->pic_id)); + atomic_and_32(&pend->pending_pics, ~__BIT(pic->pic_id)); } static void -pic_list_unblock_irqs(void) +pic_list_unblock_irqs(struct pic_pending *pend) { - uint32_t blocked_pics = pic_blocked_pics; + uint32_t blocked_pics = pend->blocked_pics; + + pend->blocked_pics = 0; - pic_blocked_pics = 0; for (;;) { struct pic_softc *pic; #if PIC_MAXSOURCES > 32 @@ -447,9 +486,9 @@ pic_list_unblock_irqs(void) struct pic_softc * -pic_list_find_pic_by_pending_ipl(uint32_t ipl_mask) +pic_list_find_pic_by_pending_ipl(struct pic_pending *pend, uint32_t ipl_mask) { - uint32_t pending_pics = pic_pending_pics; + uint32_t pending_pics = pend->pending_pics; struct pic_softc *pic; for (;;) { @@ -466,17 +505,19 @@ pic_list_find_pic_by_pending_ipl(uint32_ } void -pic_list_deliver_irqs(register_t psw, int ipl, void *frame) +pic_list_deliver_irqs(struct pic_pending *pend, register_t psw, int ipl, + void *frame) { const uint32_t ipl_mask = __BIT(ipl); struct pic_softc *pic; - while ((pic = pic_list_find_pic_by_pending_ipl(ipl_mask)) != NULL) { - pic_deliver_irqs(pic, ipl, frame); + while ((pic = pic_list_find_pic_by_pending_ipl(pend, ipl_mask)) != NULL) { + pic_deliver_irqs(pend, pic, ipl, frame); KASSERT((pic->pic_pending_ipls & ipl_mask) == 0); } - atomic_and_32(&pic_pending_ipls, ~ipl_mask); + atomic_and_32(&pend->pending_ipls, ~ipl_mask); } +#endif /* __HAVE_PIC_PENDING_INTRS */ void pic_do_pending_ints(register_t psw, int newipl, void *frame) @@ -486,19 +527,35 @@ pic_do_pending_ints(register_t psw, int KASSERTMSG(ci->ci_cpl == IPL_HIGH, "cpl %d", ci->ci_cpl); return; } - while ((pic_pending_ipls & ~__BIT(newipl)) > __BIT(newipl)) { - KASSERT(pic_pending_ipls < __BIT(NIPL)); +#if defined(__HAVE_PIC_PENDING_INTRS) +#ifdef MULTIPROCESSOR + struct pic_pending *pend = percpu_getref(pic_pending_percpu); +#else + struct pic_pending *pend = &pic_pending; +#endif + while ((pend->pending_ipls & ~__BIT(newipl)) > __BIT(newipl)) { + KASSERT(pend->pending_ipls < __BIT(NIPL)); for (;;) { - int ipl = 31 - __builtin_clz(pic_pending_ipls); + int ipl = 31 - __builtin_clz(pend->pending_ipls); KASSERT(ipl < NIPL); if (ipl <= newipl) break; pic_set_priority(ci, ipl); - pic_list_deliver_irqs(psw, ipl, frame); - pic_list_unblock_irqs(); + pic_list_deliver_irqs(pend, psw, ipl, frame); + pic_list_unblock_irqs(pend); } } +#ifdef MULTIPROCESSOR + percpu_putref(pic_pending_percpu); +#endif +#endif /* __HAVE_PIC_PENDING_INTRS */ +#ifdef __HAVE_PREEEMPTION + if (newipl == IPL_NONE && (ci->ci_astpending & __BIT(1))) { + pic_set_priority(ci, IPL_SCHED); + kpreempt(0); + } +#endif if (ci->ci_cpl != newipl) pic_set_priority(ci, newipl); } @@ -534,6 +591,15 @@ pic_percpu_allocate(void *v0, void *v1, #endif } +#if defined(__HAVE_PIC_PENDING_INTRS) && defined(MULTIPROCESSOR) +static void +pic_pending_zero(void *v0, void *v1, struct cpu_info *ci) +{ + struct pic_pending * const p = v0; + memset(p, 0, sizeof(*p)); +} +#endif /* __HAVE_PIC_PENDING_INTRS && MULTIPROCESSOR */ + void pic_add(struct pic_softc *pic, int irqbase) { @@ -541,6 +607,18 @@ pic_add(struct pic_softc *pic, int irqba KASSERT(strlen(pic->pic_name) > 0); +#if defined(__HAVE_PIC_PENDING_INTRS) && defined(MULTIPROCESSOR) + if (__predict_false(pic_pending_percpu == NULL)) { + pic_pending_percpu = percpu_alloc(sizeof(struct pic_pending)); + KASSERT(pic_pending_percpu != NULL); + + /* + * Now zero the per-cpu pending data. + */ + percpu_foreach(pic_pending_percpu, pic_pending_zero, NULL); + } +#endif /* __HAVE_PIC_PENDING_INTRS && MULTIPROCESSOR */ + for (slot = 0; slot < PIC_MAXPICS; slot++) { struct pic_softc * const xpic = pic_list[slot]; if (xpic == NULL) { @@ -594,7 +672,7 @@ pic_add(struct pic_softc *pic, int irqba KASSERT((slot == 0) == (pic->pic_ops->pic_set_priority != NULL)); #endif #ifdef MULTIPROCESSOR - KASSERT((slot == 0) == (pic->pic_ops->pic_ipi_send != NULL)); + KASSERT((pic->pic_cpus != NULL) == (pic->pic_ops->pic_ipi_send != NULL)); #endif pic_list[slot] = pic; } Index: src/sys/arch/arm/pic/picvar.h diff -u src/sys/arch/arm/pic/picvar.h:1.10.2.1 src/sys/arch/arm/pic/picvar.h:1.10.2.2 --- src/sys/arch/arm/pic/picvar.h:1.10.2.1 Sun Nov 9 16:05:25 2014 +++ src/sys/arch/arm/pic/picvar.h Thu Jul 30 09:37:37 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: picvar.h,v 1.10.2.1 2014/11/09 16:05:25 martin Exp $ */ +/* $NetBSD: picvar.h,v 1.10.2.2 2015/07/30 09:37:37 martin Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. * All rights reserved. @@ -59,11 +59,17 @@ struct cpu_info; #define NIPI 6 #endif +#if !defined(__HAVE_PIC_SET_PRIORITY) +#define __HAVE_PIC_PENDING_INTRS +#endif + int pic_handle_intr(void *); +#if defined(__HAVE_PIC_PENDING_INTRS) void pic_mark_pending(struct pic_softc *pic, int irq); void pic_mark_pending_source(struct pic_softc *pic, struct intrsource *is); uint32_t pic_mark_pending_sources(struct pic_softc *pic, size_t irq_base, uint32_t pending); +#endif /* __HAVE_PIC_PENDING_INTRS */ void *pic_establish_intr(struct pic_softc *pic, int irq, int ipl, int type, int (*func)(void *), void *arg); int pic_alloc_irq(struct pic_softc *pic); @@ -119,9 +125,14 @@ struct pic_percpu { struct pic_softc { const struct pic_ops *pic_ops; struct intrsource **pic_sources; +#ifdef __HAVE_PIC_PENDING_INTRS volatile uint32_t pic_pending_irqs[(PIC_MAXSOURCES + 31) / 32]; volatile uint32_t pic_blocked_irqs[(PIC_MAXSOURCES + 31) / 32]; volatile uint32_t pic_pending_ipls; +#endif +#ifdef MULTIPROCESSOR + kcpuset_t *pic_cpus; +#endif size_t pic_maxsources; percpu_t *pic_percpu; uint8_t pic_id; @@ -161,7 +172,7 @@ void pic_set_priority(struct cpu_info *, void pic_add(struct pic_softc *, int); void pic_do_pending_int(void); #ifdef MULTIPROCESSOR -int pic_ipi_nop(void *); +int pic_ipi_nop(void *); // IPI_KPREEMPT tto int pic_ipi_xcall(void *); int pic_ipi_generic(void *); int pic_ipi_shootdown(void *); Index: src/sys/arch/evbarm/rpi/rpi_machdep.c diff -u src/sys/arch/evbarm/rpi/rpi_machdep.c:1.43.2.4 src/sys/arch/evbarm/rpi/rpi_machdep.c:1.43.2.5 --- src/sys/arch/evbarm/rpi/rpi_machdep.c:1.43.2.4 Wed Mar 11 20:22:56 2015 +++ src/sys/arch/evbarm/rpi/rpi_machdep.c Thu Jul 30 09:37:37 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: rpi_machdep.c,v 1.43.2.4 2015/03/11 20:22:56 snj Exp $ */ +/* $NetBSD: rpi_machdep.c,v 1.43.2.5 2015/07/30 09:37:37 martin Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.43.2.4 2015/03/11 20:22:56 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.43.2.5 2015/07/30 09:37:37 martin Exp $"); #include "opt_arm_debug.h" #include "opt_bcm283x.h" @@ -518,11 +518,6 @@ rpi_bootstrap(void) __func__, i); } } - - /* - * XXXNH: Disable non-boot CPUs for now - */ - arm_cpu_hatched = 0; #endif }