Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/cortex Don't assume that CPU index = GIC CPU in...
details: https://anonhg.NetBSD.org/src/rev/5b7aef5c558e
branches: trunk
changeset: 354494:5b7aef5c558e
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sun Jun 18 22:11:50 2017 +0000
description:
Don't assume that CPU index = GIC CPU interface number. We can determine
the current CPU interface number by reading from the read-only
GICD_ITARGETSR0 through GICD_ITARGETSR7 registers.
This gets interrupts working on Exynos 5422, where the boot processor has
GIC CPU interface #4.
diffstat:
sys/arch/arm/cortex/gic.c | 39 ++++++++++++++++++++++++++++++++++-----
1 files changed, 34 insertions(+), 5 deletions(-)
diffs (91 lines):
diff -r 114b85ad3759 -r 5b7aef5c558e sys/arch/arm/cortex/gic.c
--- a/sys/arch/arm/cortex/gic.c Sun Jun 18 20:24:59 2017 +0000
+++ b/sys/arch/arm/cortex/gic.c Sun Jun 18 22:11:50 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gic.c,v 1.23 2017/06/05 20:02:11 skrll Exp $ */
+/* $NetBSD: gic.c,v 1.24 2017/06/18 22:11:50 jmcneill 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.23 2017/06/05 20:02:11 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.24 2017/06/18 22:11:50 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -100,6 +100,7 @@
#ifdef MULTIPROCESSOR
uint32_t sc_mptargets;
#endif
+ uint32_t sc_bptargets;
} armgic_softc = {
.sc_pic = {
.pic_ops = &armgic_picops,
@@ -139,6 +140,29 @@
bus_space_write_4(sc->sc_memt, sc->sc_gicdh, o, v);
}
+static uint32_t
+gicd_find_targets(struct armgic_softc *sc)
+{
+ uint32_t targets = 0;
+
+ /*
+ * GICD_ITARGETSR0 through 7 are read-only, and each field returns
+ * a value that corresponds only to the processor reading the
+ * register. Use this to determine the current processor's
+ * CPU interface number.
+ */
+ for (int i = 0; i < 8; i++) {
+ targets = gicd_read(sc, GICD_ITARGETSRn(i));
+ if (targets != 0)
+ break;
+ }
+ targets |= (targets >> 16);
+ targets |= (targets >> 8);
+ targets &= 0xff;
+
+ return targets ? targets : 1;
+}
+
/*
* In the GIC prioritization scheme, lower numbers have higher priority.
* Only write priorities that could be non-secure.
@@ -326,7 +350,7 @@
} else
#endif
#endif
- targets |= 1 << byte_shift;
+ targets |= sc->sc_bptargets << byte_shift;
gicd_write(sc, targets_reg, targets);
/*
@@ -417,11 +441,11 @@
armgic_cpu_init(struct pic_softc *pic, struct cpu_info *ci)
{
struct armgic_softc * const sc = PICTOSOFTC(pic);
- sc->sc_mptargets |= 1 << cpu_index(ci);
+ sc->sc_mptargets |= gicd_find_targets(sc);
KASSERTMSG(ci->ci_cpl == IPL_HIGH, "ipl %d not IPL_HIGH", ci->ci_cpl);
armgic_cpu_init_priorities(sc);
if (!CPU_IS_PRIMARY(ci)) {
- if (sc->sc_mptargets != 1) {
+ if (popcount(sc->sc_mptargets) != 1) {
armgic_cpu_init_targets(sc);
}
if (sc->sc_enabled_local) {
@@ -502,6 +526,11 @@
u_int priorities = 1 << popcount32(pmr);
/*
+ * Find the boot processor's CPU interface number.
+ */
+ sc->sc_bptargets = gicd_find_targets(sc);
+
+ /*
* Let's find out how many real sources we have.
*/
for (size_t i = 0, group = 0;
Home |
Main Index |
Thread Index |
Old Index