Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/alpha Changes to make MPSAFE interrupts work on Alpha:



details:   https://anonhg.NetBSD.org/src/rev/14c003b414c0
branches:  trunk
changeset: 938976:14c003b414c0
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Tue Sep 22 15:24:01 2020 +0000

description:
Changes to make MPSAFE interrupts work on Alpha:

- Remove the ipl argument to scb_set() and the associated array of
  "mpsafe" booleans initialized based on the ipl.  It was bogus
  anyway; all IPL_{BIO,NET,TTY}, etc. values are aliases of IPL_VM,
  and for all practical purposes, there is really only one device
  interrrupt level on Alpha anyway.  Intead, we now treat all dispatches
  from the SCB vector table as MP-safe, and it is now the handler for
  that vector who is responsible for acquiring the KERNEL_LOCK if needed.

- Update the direct interrupt vector handlers in jensenio and TURBOchannel
  to acquire the KERNEL_LOCK.

- Introduce a new ALPHA_INTR_MPSAFE flag, and add a flags argument to
  alpha_shared_intr_establish().  When it is set, indicate that the
  handler is MP-safe.  Update alpha_shared_intr_dispatch() to pay
  attention and acquire the KERNEL_LOCK (or not) as indicated.

- Re-factor all of the PCI interrupt handling, providing "generic PCI"
  "PCI interrupts through ISA IRQs" implementations to significantly
  reduce code duplication.  Supplement the PCI chipset tag with more
  info to facilitate this, and make the PCI interrupt-related routines
  take a pci_chipset_tag_t argument rather than a void * argument.

- Because PCI interrupts on KN8AE are dispatched directly from the
  SCB, provide a wrapper for non-MPSAFE interrupt handlers that
  acquires the KERNEL_LOCK.

- Change the pci_intr_handle_t type to be a struct rather than an
  integer type in order to catch any direct use of it as a value.
  Add a set of functions to interact with pci_intr_handle_t, including
  setting interrupt flags.

- Implement pci_intr_setattr() so that the PCI_INTR_MPSAFE attribute
  can be set on a pci_intr_handle_t.

- While I'm here, make all of the MI PCI back-end operations call
  through real functions rather than hopping directly through function
  pointers in the chipset tag.

This change looks a lot bigger than it really is because of the re-factor
in the plethora of model-specific PCI interrupt back-ends.  The KN8AE,
KN300, and T2/T3/T4 (Sable) are largely un-changed.

diffstat:

 sys/arch/alpha/alpha/interrupt.c         |   23 +-
 sys/arch/alpha/common/shared_intr.c      |   17 +-
 sys/arch/alpha/include/intr.h            |    9 +-
 sys/arch/alpha/include/pci_machdep.h     |   94 +++++---
 sys/arch/alpha/jensenio/com_jensenio.c   |    8 +-
 sys/arch/alpha/jensenio/jensenio_intr.c  |    9 +-
 sys/arch/alpha/jensenio/pckbc_jensenio.c |    8 +-
 sys/arch/alpha/pci/pci_1000.c            |  146 +++-----------
 sys/arch/alpha/pci/pci_1000a.c           |  141 ++-----------
 sys/arch/alpha/pci/pci_2100_a50.c        |   66 +-----
 sys/arch/alpha/pci/pci_2100_a500.c       |  217 ++++++++++-----------
 sys/arch/alpha/pci/pci_550.c             |  229 +++++++---------------
 sys/arch/alpha/pci/pci_6600.c            |  215 ++++++++------------
 sys/arch/alpha/pci/pci_alphabook1.c      |   67 +-----
 sys/arch/alpha/pci/pci_axppci_33.c       |   66 +-----
 sys/arch/alpha/pci/pci_eb164.c           |  201 +++----------------
 sys/arch/alpha/pci/pci_eb164_intr.s      |   15 +-
 sys/arch/alpha/pci/pci_eb64plus.c        |  168 ++--------------
 sys/arch/alpha/pci/pci_eb64plus_intr.s   |   15 +-
 sys/arch/alpha/pci/pci_eb66.c            |  168 ++--------------
 sys/arch/alpha/pci/pci_eb66_intr.s       |   15 +-
 sys/arch/alpha/pci/pci_kn20aa.c          |  153 ++------------
 sys/arch/alpha/pci/pci_kn300.c           |   89 ++++---
 sys/arch/alpha/pci/pci_kn8ae.c           |  120 +++++++----
 sys/arch/alpha/pci/pci_machdep.c         |  311 ++++++++++++++++++++++++++++++-
 sys/arch/alpha/pci/pci_up1000.c          |  117 +---------
 sys/arch/alpha/pci/pciide_machdep.c      |   10 +-
 sys/arch/alpha/pci/sio.c                 |    8 +-
 sys/arch/alpha/pci/sio_pic.c             |   92 ++++++++-
 sys/arch/alpha/pci/siovar.h              |   16 +-
 sys/arch/alpha/pci/ttwogavar.h           |    3 +-
 sys/arch/alpha/sableio/com_sableio.c     |   14 +-
 sys/arch/alpha/sableio/fdc_sableio.c     |   14 +-
 sys/arch/alpha/sableio/lpt_sableio.c     |   13 +-
 sys/arch/alpha/sableio/pckbc_sableio.c   |   11 +-
 sys/arch/alpha/tc/tc_3000_300.c          |    8 +-
 sys/arch/alpha/tc/tc_3000_500.c          |    8 +-
 sys/arch/alpha/tc/tcasic.c               |    6 +-
 38 files changed, 1200 insertions(+), 1690 deletions(-)

diffs (truncated from 4867 to 300 lines):

diff -r 18d4b5c5ae71 -r 14c003b414c0 sys/arch/alpha/alpha/interrupt.c
--- a/sys/arch/alpha/alpha/interrupt.c  Tue Sep 22 15:16:49 2020 +0000
+++ b/sys/arch/alpha/alpha/interrupt.c  Tue Sep 22 15:24:01 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: interrupt.c,v 1.88 2020/09/19 03:02:07 thorpej Exp $ */
+/* $NetBSD: interrupt.c,v 1.89 2020/09/22 15:24:01 thorpej Exp $ */
 
 /*-
  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@@ -65,7 +65,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: interrupt.c,v 1.88 2020/09/19 03:02:07 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: interrupt.c,v 1.89 2020/09/22 15:24:01 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -88,8 +88,8 @@
 #include <machine/cpuconf.h>
 #include <machine/alpha.h>
 
-struct scbvec scb_iovectab[SCB_VECTOIDX(SCB_SIZE - SCB_IOVECBASE)];
-static bool scb_mpsafe[SCB_VECTOIDX(SCB_SIZE - SCB_IOVECBASE)];
+struct scbvec scb_iovectab[SCB_VECTOIDX(SCB_SIZE - SCB_IOVECBASE)]
+                                                       __read_mostly;
 
 void   netintr(void);
 
@@ -114,7 +114,7 @@
 }
 
 void
-scb_set(u_long vec, void (*func)(void *, u_long), void *arg, int level)
+scb_set(u_long vec, void (*func)(void *, u_long), void *arg)
 {
        u_long idx;
        int s;
@@ -132,7 +132,6 @@
 
        scb_iovectab[idx].scb_func = func;
        scb_iovectab[idx].scb_arg = arg;
-       scb_mpsafe[idx] = (level != IPL_VM);
 
        splx(s);
 }
@@ -257,23 +256,17 @@
 
        case ALPHA_INTR_DEVICE: /* I/O device interrupt */
            {
-               struct scbvec *scb;
-               int idx = SCB_VECTOIDX(a1 - SCB_IOVECBASE);
-               bool mpsafe = scb_mpsafe[idx];
+               const int idx = SCB_VECTOIDX(a1 - SCB_IOVECBASE);
 
                KDASSERT(a1 >= SCB_IOVECBASE && a1 < SCB_SIZE);
 
                atomic_inc_ulong(&sc->sc_evcnt_device.ev_count);
                atomic_inc_ulong(&ci->ci_intrdepth);
 
-               if (!mpsafe) {
-                       KERNEL_LOCK(1, NULL);
-               }
                ci->ci_data.cpu_nintr++;
-               scb = &scb_iovectab[idx];
+
+               struct scbvec * const scb = &scb_iovectab[idx];
                (*scb->scb_func)(scb->scb_arg, a1);
-               if (!mpsafe)
-                       KERNEL_UNLOCK_ONE(NULL);
 
                atomic_dec_ulong(&ci->ci_intrdepth);
                break;
diff -r 18d4b5c5ae71 -r 14c003b414c0 sys/arch/alpha/common/shared_intr.c
--- a/sys/arch/alpha/common/shared_intr.c       Tue Sep 22 15:16:49 2020 +0000
+++ b/sys/arch/alpha/common/shared_intr.c       Tue Sep 22 15:24:01 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: shared_intr.c,v 1.22 2019/11/10 21:16:22 chs Exp $ */
+/* $NetBSD: shared_intr.c,v 1.23 2020/09/22 15:24:01 thorpej Exp $ */
 
 /*
  * Copyright (c) 1996 Carnegie-Mellon University.
@@ -33,7 +33,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: shared_intr.c,v 1.22 2019/11/10 21:16:22 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: shared_intr.c,v 1.23 2020/09/22 15:24:01 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -109,7 +109,14 @@
                 *  -1: This interrupt might have been for me, but I can't say
                 *      for sure.
                 */
-               rv = (*ih->ih_fn)(ih->ih_arg);
+
+               if (!ih->ih_mpsafe) {
+                       KERNEL_LOCK(1, NULL);
+                       rv = (*ih->ih_fn)(ih->ih_arg);
+                       KERNEL_UNLOCK_ONE(NULL);
+               } else {
+                       rv = (*ih->ih_fn)(ih->ih_arg);
+               }
 
                handled = handled || (rv != 0);
                ih = ih->ih_q.tqe_next;
@@ -120,7 +127,8 @@
 
 void *
 alpha_shared_intr_establish(struct alpha_shared_intr *intr, unsigned int num,
-    int type, int level, int (*fn)(void *), void *arg, const char *basename)
+    int type, int level, int flags,
+    int (*fn)(void *), void *arg, const char *basename)
 {
        struct alpha_shared_intrhand *ih;
 
@@ -166,6 +174,7 @@
        ih->ih_arg = arg;
        ih->ih_level = level;
        ih->ih_num = num;
+       ih->ih_mpsafe = (flags & ALPHA_INTR_MPSAFE) != 0;
 
        intr[num].intr_sharetype = type;
        TAILQ_INSERT_TAIL(&intr[num].intr_q, ih, ih_q);
diff -r 18d4b5c5ae71 -r 14c003b414c0 sys/arch/alpha/include/intr.h
--- a/sys/arch/alpha/include/intr.h     Tue Sep 22 15:16:49 2020 +0000
+++ b/sys/arch/alpha/include/intr.h     Tue Sep 22 15:24:01 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.78 2020/09/19 01:24:31 thorpej Exp $ */
+/* $NetBSD: intr.h,v 1.79 2020/09/22 15:24:01 thorpej Exp $ */
 
 /*-
  * Copyright (c) 2000, 2001, 2002 The NetBSD Foundation, Inc.
@@ -195,6 +195,8 @@
  * Alpha shared-interrupt-line common code.
  */
 
+#define        ALPHA_INTR_MPSAFE               0x01
+
 struct alpha_shared_intrhand {
        TAILQ_ENTRY(alpha_shared_intrhand)
                ih_q;
@@ -203,6 +205,7 @@
        void    *ih_arg;
        int     ih_level;
        unsigned int ih_num;
+       int     ih_mpsafe;
 };
 
 struct alpha_shared_intr {
@@ -225,7 +228,7 @@
 int    alpha_shared_intr_dispatch(struct alpha_shared_intr *,
            unsigned int);
 void   *alpha_shared_intr_establish(struct alpha_shared_intr *,
-           unsigned int, int, int, int (*)(void *), void *, const char *);
+           unsigned int, int, int, int, int (*)(void *), void *, const char *);
 void   alpha_shared_intr_disestablish(struct alpha_shared_intr *,
            void *, const char *);
 int    alpha_shared_intr_get_sharetype(struct alpha_shared_intr *,
@@ -254,7 +257,7 @@
 extern struct scbvec scb_iovectab[];
 
 void   scb_init(void);
-void   scb_set(u_long, void (*)(void *, u_long), void *, int);
+void   scb_set(u_long, void (*)(void *, u_long), void *);
 u_long scb_alloc(void (*)(void *, u_long), void *);
 void   scb_free(u_long);
 
diff -r 18d4b5c5ae71 -r 14c003b414c0 sys/arch/alpha/include/pci_machdep.h
--- a/sys/arch/alpha/include/pci_machdep.h      Tue Sep 22 15:16:49 2020 +0000
+++ b/sys/arch/alpha/include/pci_machdep.h      Tue Sep 22 15:24:01 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_machdep.h,v 1.18 2014/03/29 19:28:25 christos Exp $ */
+/* $NetBSD: pci_machdep.h,v 1.19 2020/09/22 15:24:01 thorpej Exp $ */
 
 /*
  * Copyright (c) 1996 Carnegie-Mellon University.
@@ -27,6 +27,11 @@
  * rights to redistribute these changes.
  */
 
+#ifndef _ALPHA_PCI_MACHDEP_H_
+#define        _ALPHA_PCI_MACHDEP_H_
+
+#include <sys/errno.h>
+
 /*
  * Machine-specific definitions for PCI autoconfiguration.
  */
@@ -37,12 +42,15 @@
  */
 typedef struct alpha_pci_chipset *pci_chipset_tag_t;
 typedef u_long pcitag_t;
-typedef u_long pci_intr_handle_t;
+typedef struct {
+       u_long value;
+} pci_intr_handle_t;
 
 /*
  * Forward declarations.
  */
 struct pci_attach_args;
+struct alpha_shared_intr;
 
 /*
  * alpha-specific PCI structure and type definitions.
@@ -62,43 +70,44 @@
        void            *pc_intr_v;
        int             (*pc_intr_map)(const struct pci_attach_args *,
                            pci_intr_handle_t *);
-       const char      *(*pc_intr_string)(void *, pci_intr_handle_t,
-                           char *, size_t);
-       const struct evcnt *(*pc_intr_evcnt)(void *, pci_intr_handle_t);
-       void            *(*pc_intr_establish)(void *, pci_intr_handle_t,
-                           int, int (*)(void *), void *);
-       void            (*pc_intr_disestablish)(void *, void *);
+       const char      *(*pc_intr_string)(pci_chipset_tag_t,
+                           pci_intr_handle_t, char *, size_t);
+       const struct evcnt *(*pc_intr_evcnt)(pci_chipset_tag_t,
+                           pci_intr_handle_t);
+       void            *(*pc_intr_establish)(pci_chipset_tag_t,
+                           pci_intr_handle_t, int, int (*)(void *), void *);
+       void            (*pc_intr_disestablish)(pci_chipset_tag_t, void *);
 
-       void            *(*pc_pciide_compat_intr_establish)(void *, device_t,
+       void            *(*pc_pciide_compat_intr_establish)(device_t,
                            const struct pci_attach_args *, int,
                            int (*)(void *), void *);
+
+       struct alpha_shared_intr *pc_shared_intrs;
+       const char      *pc_intr_desc;
+       u_long          pc_vecbase;
+       u_int           pc_nirq;
+
+       void            (*pc_intr_enable)(pci_chipset_tag_t, int);
+       void            (*pc_intr_disable)(pci_chipset_tag_t, int);
 };
 
 /*
  * Functions provided to machine-independent PCI code.
  */
-#define        pci_attach_hook(p, s, pba)                                      \
-    (*(pba)->pba_pc->pc_attach_hook)((p), (s), (pba))
-#define        pci_bus_maxdevs(c, b)                                           \
-    (*(c)->pc_bus_maxdevs)((c)->pc_conf_v, (b))
-#define        pci_make_tag(c, b, d, f)                                        \
-    (*(c)->pc_make_tag)((c)->pc_conf_v, (b), (d), (f))
-#define        pci_decompose_tag(c, t, bp, dp, fp)                             \
-    (*(c)->pc_decompose_tag)((c)->pc_conf_v, (t), (bp), (dp), (fp))
-#define        pci_conf_read(c, t, r)                                          \
-    (*(c)->pc_conf_read)((c)->pc_conf_v, (t), (r))
-#define        pci_conf_write(c, t, r, v)                                      \
-    (*(c)->pc_conf_write)((c)->pc_conf_v, (t), (r), (v))
-#define        pci_intr_map(pa, ihp)                                           \
-    (*(pa)->pa_pc->pc_intr_map)((pa), (ihp))
-#define        pci_intr_string(c, ih, buf, len)                                \
-    (*(c)->pc_intr_string)((c)->pc_intr_v, (ih), (buf), (len))
-#define        pci_intr_evcnt(c, ih)                                           \
-    (*(c)->pc_intr_evcnt)((c)->pc_intr_v, (ih))
-#define        pci_intr_establish(c, ih, l, h, a)                              \
-    (*(c)->pc_intr_establish)((c)->pc_intr_v, (ih), (l), (h), (a))
-#define        pci_intr_disestablish(c, iv)                                    \
-    (*(c)->pc_intr_disestablish)((c)->pc_intr_v, (iv))
+void   pci_attach_hook(device_t, device_t, struct pcibus_attach_args *);
+int    pci_bus_maxdevs(pci_chipset_tag_t, int);
+pcitag_t pci_make_tag(pci_chipset_tag_t, int, int, int);
+void   pci_decompose_tag(pci_chipset_tag_t, pcitag_t, int *, int *, int *);
+pcireg_t pci_conf_read(pci_chipset_tag_t, pcitag_t, int);
+void   pci_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
+
+int    pci_intr_map(const struct pci_attach_args *, pci_intr_handle_t *);
+const char *pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t,
+           char *, size_t);
+const struct evcnt *pci_intr_evcnt(pci_chipset_tag_t, pci_intr_handle_t);
+void   *pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t, int,
+           int (*)(void *), void *);
+void   pci_intr_disestablish(pci_chipset_tag_t, void *);
 
 /*
  * alpha-specific PCI functions.
@@ -106,8 +115,23 @@
  */
 void   pci_display_console(bus_space_tag_t, bus_space_tag_t,
            pci_chipset_tag_t, int, int, int);
-#define        alpha_pciide_compat_intr_establish(c, d, p, ch, f, a)           \
-    ((c)->pc_pciide_compat_intr_establish == NULL ? NULL :             \
-     (*(c)->pc_pciide_compat_intr_establish)((c)->pc_conf_v, (d), (p), \
-       (ch), (f), (a)))
 void   device_pci_register(device_t, void *);
+
+int    alpha_pci_generic_intr_map(const struct pci_attach_args *,
+           pci_intr_handle_t *);
+const char *alpha_pci_generic_intr_string(pci_chipset_tag_t,
+           pci_intr_handle_t, char *, size_t);
+const struct evcnt *alpha_pci_generic_intr_evcnt(pci_chipset_tag_t,
+           pci_intr_handle_t);
+void   *alpha_pci_generic_intr_establish(pci_chipset_tag_t,
+           pci_intr_handle_t, int, int (*)(void *), void *);
+void   alpha_pci_generic_intr_disestablish(pci_chipset_tag_t, void *);



Home | Main Index | Thread Index | Old Index