Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch RPI2 MP support.
details: https://anonhg.NetBSD.org/src/rev/d1719a2fd9b0
branches: trunk
changeset: 807490:d1719a2fd9b0
user: skrll <skrll%NetBSD.org@localhost>
date: Sun Apr 12 17:32:39 2015 +0000
description:
RPI2 MP support.
Thanks to Matt Thomas for making this possible with his changes to pic.c
diffstat:
sys/arch/arm/broadcom/bcm2835_intr.c | 189 ++++++++++++++++++++++++++--------
sys/arch/arm/broadcom/bcm2835_intr.h | 8 +-
sys/arch/arm/broadcom/bcm2835_obio.c | 15 +-
sys/arch/arm/broadcom/bcm2835reg.h | 91 +++++++++-------
sys/arch/evbarm/rpi/rpi_machdep.c | 9 +-
5 files changed, 207 insertions(+), 105 deletions(-)
diffs (truncated from 583 to 300 lines):
diff -r b8cd029daf98 -r d1719a2fd9b0 sys/arch/arm/broadcom/bcm2835_intr.c
--- a/sys/arch/arm/broadcom/bcm2835_intr.c Sun Apr 12 17:08:25 2015 +0000
+++ b/sys/arch/arm/broadcom/bcm2835_intr.c Sun Apr 12 17:32:39 2015 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: bcm2835_intr.c,v 1.7 2015/03/05 14:27:25 skrll Exp $ */
+/* $NetBSD: bcm2835_intr.c,v 1.8 2015/04/12 17:32:39 skrll 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.7 2015/03/05 14:27:25 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_intr.c,v 1.8 2015/04/12 17:32:39 skrll Exp $");
#define _INTR_PRIVATE
@@ -67,21 +67,12 @@
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 @@
.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 @@
.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 @@
};
#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 @@
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 @@
{
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 @@
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 @@
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 @@
#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,7 +361,6 @@
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) {
uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_MAILBOX_IRQS);
uint32_t val = bus_space_read_4(al_iot, al_ioh,
@@ -373,9 +382,12 @@
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;
-//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);
uint32_t val = bus_space_read_4(al_iot, al_ioh,
@@ -384,7 +396,6 @@
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) {
uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_MAILBOX_IRQS);
uint32_t val = bus_space_read_4(al_iot, al_ioh,
@@ -399,14 +410,16 @@
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 +437,99 @@
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)
+{
+ const cpuid_t cpuid = pic - &bcm2836mp_pic[0];
+
+ bus_space_write_4(al_iot, al_ioh,
+ BCM2836_LOCAL_MAILBOX0_SETN(cpuid), ipi);
+}
+
+int
+bcm2836mp_ipi_handler(void *priv)
+{
+ const struct cpu_info *ci = curcpu();
+ const cpuid_t cpuid = ci->ci_cpuid;
+ const uint32_t ipi = 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),
+ ipi);
+
+ switch (ipi) {
+ case IPI_AST:
Home |
Main Index |
Thread Index |
Old Index