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