Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/alpha Implement fast soft interrupts for Alpha. It...
details: https://anonhg.NetBSD.org/src/rev/e2845af403b6
branches: trunk
changeset: 938835:e2845af403b6
user: thorpej <thorpej%NetBSD.org@localhost>
date: Wed Sep 16 04:07:32 2020 +0000
description:
Implement fast soft interrupts for Alpha. It's not yet enabled, because
there is a bug lurking that causes problems when user space starts up,
so we'll stick with the slow path for now.
diffstat:
sys/arch/alpha/alpha/genassym.cf | 4 +-
sys/arch/alpha/alpha/interrupt.c | 157 +++++++++++++++++++++++++------
sys/arch/alpha/alpha/locore.s | 193 ++++++++++++++++++++++++++++++++++----
sys/arch/alpha/include/cpu.h | 5 +-
sys/arch/alpha/include/intr.h | 21 +++-
sys/arch/alpha/include/types.h | 3 +-
6 files changed, 319 insertions(+), 64 deletions(-)
diffs (truncated from 599 to 300 lines):
diff -r c815850c8440 -r e2845af403b6 sys/arch/alpha/alpha/genassym.cf
--- a/sys/arch/alpha/alpha/genassym.cf Tue Sep 15 23:40:03 2020 +0000
+++ b/sys/arch/alpha/alpha/genassym.cf Wed Sep 16 04:07:32 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.25 2020/09/05 18:01:42 thorpej Exp $
+# $NetBSD: genassym.cf,v 1.26 2020/09/16 04:07:32 thorpej Exp $
#
# Copyright (c) 1982, 1990, 1993
@@ -130,6 +130,7 @@
define ALPHA_PSL_IPL_MASK ALPHA_PSL_IPL_MASK
define ALPHA_PSL_IPL_0 ALPHA_PSL_IPL_0
define ALPHA_PSL_IPL_SOFT_LO ALPHA_PSL_IPL_SOFT_LO
+define ALPHA_PSL_IPL_SOFT_HI ALPHA_PSL_IPL_SOFT_HI
define ALPHA_PSL_IPL_HIGH ALPHA_PSL_IPL_HIGH
# pte bits
@@ -189,4 +190,5 @@
define CPU_INFO_CURLWP offsetof(struct cpu_info, ci_curlwp)
define CPU_INFO_IDLE_LWP offsetof(struct cpu_info, ci_data.cpu_idlelwp)
define CPU_INFO_SSIR offsetof(struct cpu_info, ci_ssir)
+define CPU_INFO_MTX_COUNT offsetof(struct cpu_info, ci_mtx_count)
define CPU_INFO_SIZEOF sizeof(struct cpu_info)
diff -r c815850c8440 -r e2845af403b6 sys/arch/alpha/alpha/interrupt.c
--- a/sys/arch/alpha/alpha/interrupt.c Tue Sep 15 23:40:03 2020 +0000
+++ b/sys/arch/alpha/alpha/interrupt.c Wed Sep 16 04:07:32 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: interrupt.c,v 1.84 2020/09/05 18:01:42 thorpej Exp $ */
+/* $NetBSD: interrupt.c,v 1.85 2020/09/16 04:07:32 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.84 2020/09/05 18:01:42 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: interrupt.c,v 1.85 2020/09/16 04:07:32 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -450,6 +450,124 @@
return (rv);
}
+#ifdef __HAVE_FAST_SOFTINTS
+
+#define SOFTINT_CLOCK_MASK __BIT(SOFTINT_CLOCK)
+#define SOFTINT_BIO_MASK __BIT(SOFTINT_BIO)
+#define SOFTINT_NET_MASK __BIT(SOFTINT_NET)
+#define SOFTINT_SERIAL_MASK __BIT(SOFTINT_SERIAL)
+
+#define ALPHA_IPL1_SOFTINTS (SOFTINT_CLOCK_MASK | SOFTINT_BIO_MASK)
+#define ALPHA_IPL2_SOFTINTS (SOFTINT_NET_MASK | SOFTINT_SERIAL_MASK)
+
+#define ALPHA_ALL_SOFTINTS (ALPHA_IPL1_SOFTINTS | ALPHA_IPL2_SOFTINTS)
+
+#define SOFTINT_TO_IPL(si) \
+ (ALPHA_PSL_IPL_SOFT_LO + ((ALPHA_IPL2_SOFTINTS >> (si)) & 1))
+
+#define SOFTINTS_ELIGIBLE(ipl) \
+ ((ALPHA_ALL_SOFTINTS << ((ipl) << 1)) & ALPHA_ALL_SOFTINTS)
+
+/* Validate some assumptions the code makes. */
+__CTASSERT(SOFTINT_TO_IPL(SOFTINT_CLOCK) == ALPHA_PSL_IPL_SOFT_LO);
+__CTASSERT(SOFTINT_TO_IPL(SOFTINT_BIO) == ALPHA_PSL_IPL_SOFT_LO);
+__CTASSERT(SOFTINT_TO_IPL(SOFTINT_NET) == ALPHA_PSL_IPL_SOFT_HI);
+__CTASSERT(SOFTINT_TO_IPL(SOFTINT_SERIAL) == ALPHA_PSL_IPL_SOFT_HI);
+
+__CTASSERT(IPL_SOFTCLOCK == ALPHA_PSL_IPL_SOFT_LO);
+__CTASSERT(IPL_SOFTBIO == ALPHA_PSL_IPL_SOFT_LO);
+__CTASSERT(IPL_SOFTNET == ALPHA_PSL_IPL_SOFT_HI);
+__CTASSERT(IPL_SOFTSERIAL == ALPHA_PSL_IPL_SOFT_HI);
+
+__CTASSERT(SOFTINT_CLOCK_MASK & 0x3);
+__CTASSERT(SOFTINT_BIO_MASK & 0x3);
+__CTASSERT(SOFTINT_NET_MASK & 0xc);
+__CTASSERT(SOFTINT_SERIAL_MASK & 0xc);
+__CTASSERT(SOFTINT_COUNT == 4);
+
+__CTASSERT((ALPHA_ALL_SOFTINTS & ~0xfUL) == 0);
+__CTASSERT(SOFTINTS_ELIGIBLE(IPL_NONE) == ALPHA_ALL_SOFTINTS);
+__CTASSERT(SOFTINTS_ELIGIBLE(IPL_SOFTCLOCK) == ALPHA_IPL2_SOFTINTS);
+__CTASSERT(SOFTINTS_ELIGIBLE(IPL_SOFTBIO) == ALPHA_IPL2_SOFTINTS);
+__CTASSERT(SOFTINTS_ELIGIBLE(IPL_SOFTNET) == 0);
+__CTASSERT(SOFTINTS_ELIGIBLE(IPL_SOFTSERIAL) == 0);
+
+/*
+ * softint_trigger:
+ *
+ * Trigger a soft interrupt.
+ */
+void
+softint_trigger(uintptr_t const machdep)
+{
+ /* No need for an atomic; called at splhigh(). */
+ KASSERT((alpha_pal_rdps() & ALPHA_PSL_IPL_MASK) == ALPHA_PSL_IPL_HIGH);
+ curcpu()->ci_ssir |= machdep;
+}
+
+/*
+ * softint_init_md:
+ *
+ * Machine-dependent initialization for a fast soft interrupt thread.
+ */
+void
+softint_init_md(lwp_t * const l, u_int const level, uintptr_t * const machdep)
+{
+ lwp_t ** lp = &l->l_cpu->ci_silwps[level];
+ KASSERT(*lp == NULL || *lp == l);
+ *lp = l;
+
+ const uintptr_t si_bit = __BIT(level);
+ KASSERT(si_bit & ALPHA_ALL_SOFTINTS);
+ *machdep = si_bit;
+}
+
+/*
+ * Helper macro.
+ *
+ * Dispatch a softint and then restart the loop so that higher
+ * priority softints are always done first.
+ */
+#define DOSOFTINT(level) \
+ if (ssir & SOFTINT_##level##_MASK) { \
+ ci->ci_ssir &= ~SOFTINT_##level##_MASK; \
+ alpha_softint_switchto(l, IPL_SOFT##level, \
+ ci->ci_silwps[SOFTINT_##level]); \
+ KASSERT((alpha_pal_rdps() & ALPHA_PSL_IPL_MASK) == \
+ ALPHA_PSL_IPL_HIGH); \
+ continue; \
+ } \
+
+/*
+ * alpha_softint_dispatch:
+ *
+ * Process pending soft interrupts that are eligible to run
+ * at the specified new IPL. Must be called at splhigh().
+ */
+void
+alpha_softint_dispatch(int const ipl)
+{
+ struct lwp * const l = curlwp;
+ struct cpu_info * const ci = l->l_cpu;
+ unsigned long ssir;
+ const unsigned long eligible = SOFTINTS_ELIGIBLE(ipl);
+
+ KASSERT((alpha_pal_rdps() & ALPHA_PSL_IPL_MASK) == ALPHA_PSL_IPL_HIGH);
+
+ for (;;) {
+ ssir = ci->ci_ssir & eligible;
+ if (ssir == 0)
+ break;
+
+ DOSOFTINT(SERIAL);
+ DOSOFTINT(NET);
+ DOSOFTINT(BIO);
+ DOSOFTINT(CLOCK);
+ }
+}
+
+#endif /* __HAVE_FAST_SOFTINTS */
+
/*
* spllower:
*
@@ -457,42 +575,19 @@
* interrupts.
*/
void
-spllower(int ipl)
+spllower(int const ipl)
{
- if (ipl == ALPHA_PSL_IPL_0 && curcpu()->ci_ssir) {
- (void) alpha_pal_swpipl(ALPHA_PSL_IPL_SOFT_LO);
- softintr_dispatch();
+#ifdef __HAVE_FAST_SOFTINTS
+ if (ipl < ALPHA_PSL_IPL_SOFT_HI && curcpu()->ci_ssir) {
+ (void) alpha_pal_swpipl(ALPHA_PSL_IPL_HIGH);
+ alpha_softint_dispatch(ipl);
}
+#endif /* __HAVE_FAST_SOFTINTS */
(void) alpha_pal_swpipl(ipl);
}
/*
- * softintr_dispatch:
- *
- * Process pending software interrupts.
- */
-void
-softintr_dispatch(void)
-{
-
- /* XXX Nothing until alpha gets __HAVE_FAST_SOFTINTS */
-}
-
-#ifdef __HAVE_FAST_SOFTINTS
-/*
- * softint_trigger:
- *
- * Trigger a soft interrupt.
- */
-void
-softint_trigger(uintptr_t machdep)
-{
- atomic_or_ulong(&curcpu()->ci_ssir, 1 << (x))
-}
-#endif
-
-/*
* cpu_intr_p:
*
* Return non-zero if executing in interrupt context.
diff -r c815850c8440 -r e2845af403b6 sys/arch/alpha/alpha/locore.s
--- a/sys/arch/alpha/alpha/locore.s Tue Sep 15 23:40:03 2020 +0000
+++ b/sys/arch/alpha/alpha/locore.s Wed Sep 16 04:07:32 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.s,v 1.132 2020/09/05 18:01:42 thorpej Exp $ */
+/* $NetBSD: locore.s,v 1.133 2020/09/16 04:07:32 thorpej Exp $ */
/*-
* Copyright (c) 1999, 2000, 2019 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
#include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.132 2020/09/05 18:01:42 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.133 2020/09/16 04:07:32 thorpej Exp $");
#include "assym.h"
@@ -243,19 +243,28 @@
br pv, 1f
1: LDGP(pv)
- ldq s1, (FRAME_PS * 8)(sp) /* get the saved PS */
- and s1, ALPHA_PSL_IPL_MASK, t0 /* look at the saved IPL */
- bne t0, 5f /* != 0: can't do AST or SIR */
+ ldq s1, (FRAME_PS * 8)(sp) /* s1 = new PSL */
+ and s1, ALPHA_PSL_IPL_MASK, s3 /* s3 = new ipl */
+
+ /* --- BEGIN inline spllower() --- */
+
+ cmpult s3, ALPHA_PSL_IPL_SOFT_HI, t1 /* new IPL < SOFT_HI? */
+ beq t1, 5f /* no, can't do AST or SI */
+ /* yes */
/* GET_CURLWP clobbers v0, t0, t8...t11. */
GET_CURLWP
mov v0, s0 /* s0 = curlwp */
+#ifdef __HAVE_FAST_SOFTINTS
/* see if a soft interrupt is pending. */
2: ldq t1, L_CPU(s0) /* t1 = curlwp->l_cpu */
ldq t1, CPU_INFO_SSIR(t1) /* soft int pending? */
bne t1, 6f /* yes */
/* no */
+#endif /* __HAVE_FAST_SOFTINTS */
+
+ /* --- END inline spllower() --- */
and s1, ALPHA_PSL_USERMODE, t0 /* are we returning to user? */
beq t0, 5f /* no: just return */
@@ -282,16 +291,19 @@
.set at
/* NOTREACHED */
- /* We've got a SIR */
-6: ldiq a0, ALPHA_PSL_IPL_SOFT_LO
+#ifdef __HAVE_FAST_SOFTINTS
+ /* We've got a softint */
+6: ldiq a0, ALPHA_PSL_IPL_HIGH
call_pal PAL_OSF1_swpipl
mov v0, s2 /* remember old IPL */
- CALL(softintr_dispatch)
+ mov s3, a0 /* pass new ipl */
+ CALL(alpha_softint_dispatch)
- /* SIR handled; restore IPL and check again */
+ /* SI handled; restore IPL and check again */
mov s2, a0
call_pal PAL_OSF1_swpipl
br 2b
+#endif /* __HAVE_FAST_SOFTINTS */
/* We've got an AST */
7: stl zero, L_MD_ASTPENDING(s0) /* no AST pending */
@@ -643,13 +655,117 @@
/**************************************************************************/
+#ifdef __HAVE_FAST_SOFTINTS
+/*
+ * void alpha_softint_switchto(struct lwp *current, int ipl, struct lwp *next)
+ * Switch away from the current LWP to the specified softint LWP, and
+ * dispatch to softint processing.
+ * Aguments:
+ * a0 'struct lwp *' of the LWP to switch from
Home |
Main Index |
Thread Index |
Old Index