Implement wakeup interrupts on amd64. Provide a dummy implementation for
authorkettenis <kettenis@openbsd.org>
Sun, 26 May 2024 13:37:31 +0000 (13:37 +0000)
committerkettenis <kettenis@openbsd.org>
Sun, 26 May 2024 13:37:31 +0000 (13:37 +0000)
i386 such that we can call the necessary hooks in the suspend/resume code
without adding #ifdefs.  Tweak the arm64 implementation such that we can
call the hooks earlier as this is necessary to mask MSI and MSI-X
interrupts on arm64.

ok deraadt@, mlarkin@

sys/arch/amd64/amd64/acpi_machdep.c
sys/arch/amd64/amd64/intr.c
sys/arch/amd64/include/intr.h
sys/arch/amd64/include/intrdefs.h
sys/arch/arm64/arm64/cpu.c
sys/arch/arm64/arm64/intr.c
sys/arch/i386/i386/machdep.c
sys/arch/i386/include/intr.h
sys/kern/subr_suspend.c

index 6980217..bf7add7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: acpi_machdep.c,v 1.108 2023/06/07 04:46:09 deraadt Exp $      */
+/*     $OpenBSD: acpi_machdep.c,v 1.109 2024/05/26 13:37:31 kettenis Exp $     */
 /*
  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
  *
@@ -333,7 +333,8 @@ acpi_attach_machdep(struct acpi_softc *sc)
        extern void (*cpuresetfn)(void);
 
        sc->sc_interrupt = isa_intr_establish(NULL, sc->sc_fadt->sci_int,
-           IST_LEVEL, IPL_BIO, acpi_interrupt, sc, sc->sc_dev.dv_xname);
+           IST_LEVEL, IPL_BIO | IPL_WAKEUP, acpi_interrupt,
+           sc, sc->sc_dev.dv_xname);
        cpuresetfn = acpi_reset;
 
 #ifndef SMALL_KERNEL
index 64396b3..9b1182e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: intr.c,v 1.56 2024/01/19 18:38:16 kettenis Exp $      */
+/*     $OpenBSD: intr.c,v 1.57 2024/05/26 13:37:31 kettenis Exp $      */
 /*     $NetBSD: intr.c,v 1.3 2003/03/03 22:16:20 fvdl Exp $    */
 
 /*
@@ -354,8 +354,8 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
                panic("intr_establish: non-legacy IRQ on i8259");
 #endif
 
-       flags = level & IPL_MPSAFE;
-       level &= ~IPL_MPSAFE;
+       flags = level & (IPL_MPSAFE | IPL_WAKEUP);
+       level &= ~(IPL_MPSAFE | IPL_WAKEUP);
 
        KASSERT(level <= IPL_TTY || level >= IPL_CLOCK || flags & IPL_MPSAFE);
 
@@ -694,6 +694,52 @@ intr_barrier(void *cookie)
        sched_barrier(ih->ih_cpu);
 }
 
+#ifdef SUSPEND
+
+void
+intr_enable_wakeup(void)
+{
+       struct cpu_info *ci = curcpu();
+       struct pic *pic;
+       int irq, pin;
+
+       for (irq = 0; irq < MAX_INTR_SOURCES; irq++) {
+               if (ci->ci_isources[irq] == NULL)
+                       continue;
+
+               if (ci->ci_isources[irq]->is_handlers->ih_flags & IPL_WAKEUP)
+                       continue;
+
+               pic = ci->ci_isources[irq]->is_pic;
+               pin = ci->ci_isources[irq]->is_pin;
+               if (pic->pic_hwmask)
+                       pic->pic_hwmask(pic, pin);
+       }
+}
+
+void
+intr_disable_wakeup(void)
+{
+       struct cpu_info *ci = curcpu();
+       struct pic *pic;
+       int irq, pin;
+
+       for (irq = 0; irq < MAX_INTR_SOURCES; irq++) {
+               if (ci->ci_isources[irq] == NULL)
+                       continue;
+
+               if (ci->ci_isources[irq]->is_handlers->ih_flags & IPL_WAKEUP)
+                       continue;
+
+               pic = ci->ci_isources[irq]->is_pic;
+               pin = ci->ci_isources[irq]->is_pin;
+               if (pic->pic_hwunmask)
+                       pic->pic_hwunmask(pic, pin);
+       }
+}
+
+#endif
+
 /*
  * Add a mask to cpl, and return the old value of cpl.
  */
index 2fe24d3..9f0c717 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: intr.h,v 1.33 2021/12/14 18:16:14 deraadt Exp $       */
+/*     $OpenBSD: intr.h,v 1.34 2024/05/26 13:37:31 kettenis Exp $      */
 /*     $NetBSD: intr.h,v 1.2 2003/05/04 22:01:56 fvdl Exp $    */
 
 /*-
@@ -206,6 +206,8 @@ int intr_handler(struct intrframe *, struct intrhand *);
 void cpu_intr_init(struct cpu_info *);
 void intr_printconfig(void);
 void intr_barrier(void *);
+void intr_enable_wakeup(void);
+void intr_disable_wakeup(void);
 
 #ifdef MULTIPROCESSOR
 void x86_send_ipi(struct cpu_info *, int);
index 9b6de3c..048d020 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: intrdefs.h,v 1.23 2024/01/04 20:50:43 kettenis Exp $  */
+/*     $OpenBSD: intrdefs.h,v 1.24 2024/05/26 13:37:31 kettenis Exp $  */
 /*     $NetBSD: intrdefs.h,v 1.2 2003/05/04 22:01:56 fvdl Exp $        */
 
 #ifndef _AMD64_INTRDEFS_H
@@ -36,6 +36,7 @@
 
 #define        IPL_MPFLOOR     IPL_TTY
 #define        IPL_MPSAFE      0x100
+#define        IPL_WAKEUP      0x200
 
 /* Interrupt sharing types. */
 #define        IST_NONE        0       /* none */
index 2bfb445..112afeb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.c,v 1.114 2024/04/13 14:19:39 kettenis Exp $      */
+/*     $OpenBSD: cpu.c,v 1.115 2024/05/26 13:37:31 kettenis Exp $      */
 
 /*
  * Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
@@ -1526,7 +1526,8 @@ cpu_suspend_primary(void)
         * wake us up by clearing the flag.
         */
        cpu_suspended = 1;
-       intr_enable_wakeup();
+       arm_intr_func.setipl(IPL_NONE);
+       intr_enable();
 
        while (cpu_suspended) {
 #if NPSCI > 0
@@ -1542,7 +1543,8 @@ cpu_suspend_primary(void)
        }
 
 resume:
-       intr_disable_wakeup();
+       intr_disable();
+       arm_intr_func.setipl(IPL_HIGH);
 
        /* Unmask clock interrupts. */
        WRITE_SPECIALREG(cntv_ctl_el0,
index 34dd9c5..9e69fd0 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.27 2022/12/21 22:30:42 kettenis Exp $ */
+/* $OpenBSD: intr.c,v 1.28 2024/05/26 13:37:31 kettenis Exp $ */
 /*
  * Copyright (c) 2011 Dale Rahn <drahn@openbsd.org>
  *
@@ -888,15 +888,11 @@ intr_enable_wakeup(void)
 {
        if (arm_intr_func.enable_wakeup)
                arm_intr_func.enable_wakeup();
-       arm_intr_func.setipl(IPL_NONE);
-       intr_enable();
 }
 
 void
 intr_disable_wakeup(void)
 {
-       intr_disable();
-       arm_intr_func.setipl(IPL_HIGH);
        if (arm_intr_func.disable_wakeup)
                arm_intr_func.disable_wakeup();
 }
index c7edd20..a75259a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: machdep.c,v 1.670 2024/04/29 00:29:48 jsg Exp $       */
+/*     $OpenBSD: machdep.c,v 1.671 2024/05/26 13:37:32 kettenis Exp $  */
 /*     $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $    */
 
 /*-
@@ -3966,6 +3966,20 @@ intr_barrier(void *ih)
        sched_barrier(NULL);
 }
 
+#ifdef SUSPEND
+
+void
+intr_enable_wakeup(void)
+{
+}
+
+void
+intr_disable_wakeup(void)
+{
+}
+
+#endif
+
 unsigned int
 cpu_rnd_messybits(void)
 {
index 60fe6dc..9682673 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: intr.h,v 1.49 2021/12/14 18:16:14 deraadt Exp $       */
+/*     $OpenBSD: intr.h,v 1.50 2024/05/26 13:37:32 kettenis Exp $      */
 /*     $NetBSD: intr.h,v 1.5 1996/05/13 06:11:28 mycroft Exp $ */
 
 /*
@@ -128,6 +128,8 @@ void splassert_check(int, const char *);
 struct cpu_info;
 
 void intr_barrier(void *);
+void intr_enable_wakeup(void);
+void intr_disable_wakeup(void);
 
 #ifdef MULTIPROCESSOR
 void i386_send_ipi(struct cpu_info *, int);
index 1b4f406..40f7fa7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_suspend.c,v 1.16 2023/07/12 18:40:06 cheloha Exp $ */
+/* $OpenBSD: subr_suspend.c,v 1.17 2024/05/26 13:37:32 kettenis Exp $ */
 /*
  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
  * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -132,6 +132,7 @@ top:
        s = splhigh();
        intr_disable(); /* PSL_I for resume; PIC/APIC broken until repair */
        cold = 2;       /* Force other code to delay() instead of tsleep() */
+       intr_enable_wakeup();
 
        if (config_suspend_all(DVACT_SUSPEND) != 0) {
                sleep_abort(v);
@@ -172,6 +173,7 @@ fail_pts:
        config_suspend_all(DVACT_RESUME);
 
 fail_suspend:
+       intr_disable_wakeup();
        cold = 0;
        intr_enable();
        splx(s);