diff options
author | 2017-03-07 16:11:18 +0000 | |
---|---|---|
committer | 2017-03-07 16:11:18 +0000 | |
commit | e851b7eacd1b51bdfb01d30cfa480378dd69f850 (patch) | |
tree | a33ca28169b2c09a3e5d2e8b6ebb36d6d5cf2f43 | |
parent | Digest::SHA is nasty: it shows an incomplete error message if the (diff) | |
download | wireguard-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.c | 18 |
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); |