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 <[email protected]>
> >
> > 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 <[email protected]>
> > > >
> > > > 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;
}