On Fri, Jul 15, 2022 at 06:58:33PM +0200, Mark Kettenis wrote: > > Date: Mon, 11 Jul 2022 16:21:39 +0200 > > From: Anton Lindqvist <an...@basename.se> > > > > On Mon, Jul 11, 2022 at 09:02:20AM +0200, Mark Kettenis wrote: > > > > Date: Mon, 11 Jul 2022 08:35:44 +0200 > > > > From: Anton Lindqvist <an...@basename.se> > > > > > > > > Hi, > > > > Addressing the following nits made it easier for me to grasp the ampintc > > > > implementation while reading the specification. There's also one missing > > > > NULL check included. > > > > > > > > Too verbose or does anyone else consider this an improvement? > > > > > > Your timing is a but unfortunate since I just posted the > > > suspend/resume diff that will conflict with this. > > > > > > Some/all of this may be useful, but not right now :(. > > > > That was actually the thing that reminded me about this diff :) > > I can wait until things have stabilized and send out a new diff. > > Right. I actually have another change coming, but that one won't > conflict.
Here's the rebased diff. diff --git sys/arch/arm64/dev/ampintc.c sys/arch/arm64/dev/ampintc.c index 45a15dd2d57..c569c88cc2b 100644 --- sys/arch/arm64/dev/ampintc.c +++ sys/arch/arm64/dev/ampintc.c @@ -125,6 +125,13 @@ #define ICPHPIR 0x18 #define ICPIIR 0xFC +/* Sofware Generated Interrupts (SGI) */ +#define SGI_MIN 0 +#define SGI_MAX 15 +/* Private Peripheral Interrupts (PPI) */ +#define PPI_MIN 16 +#define PPI_MAX 31 + /* * what about periph_id and component_id */ @@ -237,7 +244,7 @@ ampintc_attach(struct device *parent, struct device *self, void *aux) { struct ampintc_softc *sc = (struct ampintc_softc *)self; struct fdt_attach_args *faa = aux; - int i, nintr, ncpu; + int i, ncpu, nintr, nlines; uint32_t ictr; #ifdef MULTIPROCESSOR int nipi, ipiirq[3]; @@ -262,8 +269,9 @@ ampintc_attach(struct device *parent, struct device *self, void *aux) evcount_attach(&sc->sc_spur, "irq1023/spur", NULL); ictr = bus_space_read_4(sc->sc_iot, sc->sc_d_ioh, ICD_ICTR); - nintr = 32 * ((ictr >> ICD_ICTR_ITL_SH) & ICD_ICTR_ITL_M); - nintr += 32; /* ICD_ICTR + 1, irq 0-31 is SGI, 32+ is PPI */ + nlines = (ictr >> ICD_ICTR_ITL_SH) & ICD_ICTR_ITL_M; + /* Account for SGI + PPI = 16 + 16 = 32 */ + nintr = 32 * (nlines + 1); sc->sc_nintr = nintr; ncpu = ((ictr >> ICD_ICTR_CPU_SH) & ICD_ICTR_CPU_M) + 1; printf(" nirq %d, ncpu %d", nintr, ncpu); @@ -302,7 +310,7 @@ ampintc_attach(struct device *parent, struct device *self, void *aux) * the non-secure OS. */ nipi = 0; - for (i = 0; i < 16; i++) { + for (i = 0; i <= SGI_MAX; i++) { int reg, oldreg; oldreg = bus_space_read_1(sc->sc_iot, sc->sc_d_ioh, @@ -417,7 +425,8 @@ ampintc_activate(struct device *self, int act) void ampintc_init(struct ampintc_softc *sc) { - int i; + uint32_t ictr; + int i, nconfigs, nlines; /* Disable all interrupts, clear all pending */ for (i = 0; i < sc->sc_nintr / 32; i++) { @@ -432,8 +441,20 @@ ampintc_init(struct ampintc_softc *sc) /* target no cpus */ bus_space_write_1(sc->sc_iot, sc->sc_d_ioh, ICD_IPTRn(i), 0); } - for (i = 2; i < sc->sc_nintr / 16; i++) { - /* irq 32 - N */ + + /* + * Reset edge/level configuration for all interrupts where each + * interrupt is represented using 2 bits and each configuration register + * being 32 bits wide. Each configuration register therefore covers 16 + * configurations. + * + * Since SGI are read only and PPI might not be programmable skip the + * first 2*(16 + 16)/32 = 2 configuration registers. + */ + ictr = bus_space_read_4(sc->sc_iot, sc->sc_d_ioh, ICD_ICTR); + nlines = (ictr >> ICD_ICTR_ITL_SH) & ICD_ICTR_ITL_M; + nconfigs = 2 * (nlines + 1); + for (i = 2; i < nconfigs; i++) { bus_space_write_4(sc->sc_iot, sc->sc_d_ioh, ICD_ICRn(i * 16), 0); } @@ -828,10 +849,10 @@ ampintc_intr_establish(int irqno, int type, int level, struct cpu_info *ci, if (ci == NULL) ci = &cpu_info_primary; - if (irqno < 16) { + if (irqno <= SGI_MAX) { /* SGI are only EDGE */ type = IST_EDGE_RISING; - } else if (irqno < 32) { + } else if (irqno <= PPI_MAX) { /* PPI are only LEVEL */ type = IST_LEVEL_HIGH; }