summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2017-03-07 16:11:18 +0000
committerkettenis <kettenis@openbsd.org>2017-03-07 16:11:18 +0000
commite851b7eacd1b51bdfb01d30cfa480378dd69f850 (patch)
treea33ca28169b2c09a3e5d2e8b6ebb36d6d5cf2f43
parentDigest::SHA is nasty: it shows an incomplete error message if the (diff)
downloadwireguard-openbsd-e851b7eacd1b51bdfb01d30cfa480378dd69f850.tar.xz
wireguard-openbsd-e851b7eacd1b51bdfb01d30cfa480378dd69f850.zip
Record the target mask for the boot CPU when we attach and use that to pick
the target CPU interface when establishing an interrupt. Makes interrupts work on machines that boot up on a CPU that is attached to a CPU interface that isn't zero. Discussed with Dale Rahn.
-rw-r--r--sys/arch/arm/cortex/ampintc.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/sys/arch/arm/cortex/ampintc.c b/sys/arch/arm/cortex/ampintc.c
index e62c8375968..d381b1b8ca9 100644
--- a/sys/arch/arm/cortex/ampintc.c
+++ b/sys/arch/arm/cortex/ampintc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ampintc.c,v 1.17 2017/02/07 21:23:25 patrick Exp $ */
+/* $OpenBSD: ampintc.c,v 1.18 2017/03/07 16:11:18 kettenis Exp $ */
/*
* Copyright (c) 2007,2009,2011 Dale Rahn <drahn@openbsd.org>
*
@@ -132,6 +132,7 @@ struct ampintc_softc {
int sc_nintr;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_d_ioh, sc_p_ioh;
+ int sc_boot_cpu_mask;
struct evcount sc_spur;
struct interrupt_controller sc_ic;
};
@@ -239,6 +240,12 @@ ampintc_attach(struct device *parent, struct device *self, void *aux)
sc->sc_nintr = nintr;
printf(" nirq %d\n", nintr);
+ /* Uniprocessor implementations may return zero. */
+ sc->sc_boot_cpu_mask = bus_space_read_1(sc->sc_iot, sc->sc_d_ioh,
+ ICD_IPTRn(0));
+ if (sc->sc_boot_cpu_mask == 0)
+ sc->sc_boot_cpu_mask = 0x01;
+
/* Disable all interrupts, clear all pending */
for (i = 0; i < nintr/32; i++) {
bus_space_write_4(sc->sc_iot, sc->sc_d_ioh,
@@ -351,7 +358,9 @@ ampintc_calc_mask(void)
struct cpu_info *ci = curcpu();
struct ampintc_softc *sc = ampintc;
struct intrhand *ih;
- int irq;
+ int irq, cpu;
+
+ cpu = ffs(sc->sc_boot_cpu_mask) - 1;
for (irq = 0; irq < sc->sc_nintr; irq++) {
int max = IPL_NONE;
@@ -378,11 +387,10 @@ ampintc_calc_mask(void)
if (min != IPL_NONE) {
ampintc_set_priority(irq, min);
ampintc_intr_enable(irq);
- ampintc_route(irq, IRQ_ENABLE, 0);
+ ampintc_route(irq, IRQ_ENABLE, cpu);
} else {
ampintc_intr_disable(irq);
- ampintc_route(irq, IRQ_DISABLE, 0);
-
+ ampintc_route(irq, IRQ_DISABLE, cpu);
}
}
ampintc_setipl(ci->ci_cpl);