Module Name: src
Committed By: thorpej
Date: Sun Jan 14 22:32:32 UTC 2024
Modified Files:
src/distrib/sets/lists/comp: ad.m68k
src/sys/arch/m68k/include: Makefile
Added Files:
src/sys/arch/m68k/include: intr.h
src/sys/arch/m68k/m68k: m68k_intr.c m68k_intr_stubs.s
Log Message:
Add a common m68k interrupt dispatch implementation.
To generate a diff of this commit:
cvs rdiff -u -r1.70 -r1.71 src/distrib/sets/lists/comp/ad.m68k
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/m68k/include/Makefile
cvs rdiff -u -r0 -r1.1 src/sys/arch/m68k/include/intr.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/m68k/m68k/m68k_intr.c \
src/sys/arch/m68k/m68k/m68k_intr_stubs.s
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/distrib/sets/lists/comp/ad.m68k
diff -u src/distrib/sets/lists/comp/ad.m68k:1.70 src/distrib/sets/lists/comp/ad.m68k:1.71
--- src/distrib/sets/lists/comp/ad.m68k:1.70 Wed Dec 27 19:22:11 2023
+++ src/distrib/sets/lists/comp/ad.m68k Sun Jan 14 22:32:32 2024
@@ -1,4 +1,4 @@
-# $NetBSD: ad.m68k,v 1.70 2023/12/27 19:22:11 thorpej Exp $
+# $NetBSD: ad.m68k,v 1.71 2024/01/14 22:32:32 thorpej Exp $
./usr/bin/elf2aout comp-sysutil-bin
./usr/include/gcc-4.5/math-68881.h comp-obsolete obsolete
./usr/include/gcc-4.5/tgmath.h comp-obsolete obsolete
@@ -48,6 +48,7 @@
./usr/include/m68k/int_limits.h comp-c-include
./usr/include/m68k/int_mwgwtypes.h comp-c-include
./usr/include/m68k/int_types.h comp-c-include
+./usr/include/m68k/intr.h comp-c-include
./usr/include/m68k/kcore.h comp-c-include
./usr/include/m68k/limits.h comp-c-include
./usr/include/m68k/lock.h comp-c-include
Index: src/sys/arch/m68k/include/Makefile
diff -u src/sys/arch/m68k/include/Makefile:1.34 src/sys/arch/m68k/include/Makefile:1.35
--- src/sys/arch/m68k/include/Makefile:1.34 Wed Dec 27 19:22:10 2023
+++ src/sys/arch/m68k/include/Makefile Sun Jan 14 22:32:32 2024
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.34 2023/12/27 19:22:10 thorpej Exp $
+# $NetBSD: Makefile,v 1.35 2024/01/14 22:32:32 thorpej Exp $
INCSDIR= /usr/include/m68k
@@ -10,6 +10,7 @@ INCS= ansi.h aout_machdep.h asm.h asm_si
fenv.h float.h fpreg.h frame.h \
ieee.h ieeefp.h \
int_const.h int_fmtio.h int_limits.h int_mwgwtypes.h int_types.h \
+ intr.h \
kcore.h \
limits.h lock.h \
m68k.h math.h mcontext.h mmu_30.h mmu_40.h mmu_51.h mutex.h \
Added files:
Index: src/sys/arch/m68k/include/intr.h
diff -u /dev/null src/sys/arch/m68k/include/intr.h:1.1
--- /dev/null Sun Jan 14 22:32:32 2024
+++ src/sys/arch/m68k/include/intr.h Sun Jan 14 22:32:32 2024
@@ -0,0 +1,168 @@
+/* $NetBSD: intr.h,v 1.1 2024/01/14 22:32:32 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 2023, 2024 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _M68k_INTR_H_
+#define _M68k_INTR_H_
+
+#include <sys/types.h>
+#include <machine/psl.h>
+
+/*
+ * Logical interrupt priority levels -- these are distinct from
+ * the hardware interrupt priority levels of the m68k.
+ */
+#define IPL_NONE 0
+#define IPL_SOFTCLOCK 1 /* clock software interrupts */
+#define IPL_SOFTBIO 2 /* block device software interrupts */
+#define IPL_SOFTNET 3 /* network software interrupts */
+#define IPL_SOFTSERIAL 4 /* serial device software interrupts */
+#define IPL_VM 5 /* all interrupts that can allocate memory */
+#define IPL_SCHED 6 /* scheduler / hard clock interrupts */
+#define IPL_HIGH 7 /* blocks all interrupts */
+#define NIPL 8
+
+#if defined(_KERNEL) || defined(_KMEMUSER)
+typedef struct {
+ uint16_t _psl; /* physical manifestation of logical IPL_* */
+} ipl_cookie_t;
+#endif
+
+#ifdef _KERNEL
+extern int idepth; /* interrupt depth */
+extern const uint16_t ipl2psl_table[NIPL];
+
+typedef int ipl_t; /* logical IPL_* value */
+
+static inline bool
+cpu_intr_p(void)
+{
+ return idepth != 0;
+}
+
+static inline ipl_cookie_t
+makeiplcookie(ipl_t ipl)
+{
+ return (ipl_cookie_t){._psl = ipl2psl_table[ipl]};
+}
+
+static inline int
+splraiseipl(ipl_cookie_t icookie)
+{
+ return _splraise(icookie._psl);
+}
+
+/*
+ * These are essentially constant equivalents of what's in
+ * ipl2psl_table[] to avoid the memory reference.
+ */
+#define splsoftclock() _splraise(PSL_S | MACHINE_PSL_IPL_SOFTCLOCK)
+#define splsoftbio() _splraise(PSL_S | MACHINE_PSL_IPL_SOFTBIO)
+#define splsoftnet() _splraise(PSL_S | MACHINE_PSL_IPL_SOFTNET)
+#define splsoftserial() _splraise(PSL_S | MACHINE_PSL_IPL_SOFTSERIAL)
+#define splvm() _splraise(PSL_S | MACHINE_PSL_IPL_VM)
+#define splsched() _splraise(PSL_S | MACHINE_PSL_IPL_SCHED)
+#define splhigh() spl7()
+
+/*
+ * XXX TODO: Support for hardware-assisted soft interrupts (sun68k)
+ * XXX and fast-soft-interrupts (others).
+ */
+#define spl0() _spl0()
+#define splx(s) _splx(s)
+
+#ifdef _M68K_INTR_PRIVATE
+#include <sys/queue.h>
+
+struct m68k_intrhand {
+ LIST_ENTRY(m68k_intrhand) ih_link;
+ int (*ih_func)(void *);
+ void *ih_arg;
+ struct evcnt *ih_evcnt;
+ int ih_ipl; /* m68k IPL, not IPL_* */
+ int ih_vec;
+};
+LIST_HEAD(m68k_intrhand_list, m68k_intrhand);
+
+struct m68k_ih_allocfuncs {
+ struct m68k_intrhand * (*alloc)(int km_flag);
+ void (*free)(struct m68k_intrhand *);
+};
+#else
+struct m68k_ih_allocfuncs;
+#endif /* _M68K_INTR_PRIVATE */
+
+struct evcnt;
+
+/*
+ * Common m68k interrupt dispatch:
+ *
+ * ==> m68k_intr_init(const struct m68k_ih_allocfuncs *allocfuncs)
+ *
+ * Initialize the interrupt system. If the platform needs to store
+ * additional information in the interrupt handle, then it can provide
+ * its own alloc/free routines. Otherwise, pass NULL to get the default.
+ * If a platform doesn't want the special allocator behavior, calling
+ * this function is optional; it will be done for you on the first call
+ * to m68k_intr_establish().
+ *
+ * ==> m68k_intr_establish(int (*func)(void *), void *arg,
+ * struct evcnt *ev, int vec, int ipl, int flags)
+ *
+ * Establish an interrupt handler. If vec is 0, then the handler is
+ * registered in the auto-vector list corresponding to the specified
+ * m68k interrupt priroity level (this is NOT an IPL_* value). Otherwise.
+ * the handler is registered at the specified vector.
+ *
+ * Vectored interrupts are not sharable. The interrupt vector must be
+ * within the platform's "user vector" region, which is generally defined
+ * as vectors 64-255, although some platforms may use vectors that start
+ * below 64 (in which case, that platform must define MACHINE_USERVEC_START
+ * to override the default).
+ *
+ * Vectored interrupt support is not included by default in order to reduce
+ * the memory footprint. If a platform wishes to enable vectored interrupts,
+ * then it should define __HAVE_M68K_INTR_VECTORED in its <machine/types.h>
+ * and genassym.cf.
+ *
+ * ==> m68k_intr_disestablish(void *ih)
+ *
+ * Removes a previously-established interrupt handler. Returns true
+ * if there are no more handlers on the list that handler was on. This
+ * information can be used to e.g. disable interrupts on a PIC.
+ */
+void m68k_intr_init(const struct m68k_ih_allocfuncs *);
+void *m68k_intr_establish(int (*)(void *), void *, struct evcnt *,
+ int/*vec*/, int/*m68k ipl*/, int/*isrpri*/, int/*flags*/);
+bool m68k_intr_disestablish(void *);
+
+#endif /* _KERNEL */
+
+#endif /* _M68k_INTR_H_ */
Index: src/sys/arch/m68k/m68k/m68k_intr.c
diff -u /dev/null src/sys/arch/m68k/m68k/m68k_intr.c:1.1
--- /dev/null Sun Jan 14 22:32:32 2024
+++ src/sys/arch/m68k/m68k/m68k_intr.c Sun Jan 14 22:32:32 2024
@@ -0,0 +1,375 @@
+/* $NetBSD: m68k_intr.c,v 1.1 2024/01/14 22:32:32 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1996, 2023, 2024 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Common interrupt handling for m68k platforms.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: m68k_intr.c,v 1.1 2024/01/14 22:32:32 thorpej Exp $");
+
+#define _M68K_INTR_PRIVATE
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kmem.h>
+#include <sys/vmmeter.h>
+#include <sys/device.h>
+#include <sys/cpu.h>
+#include <sys/bus.h>
+#include <sys/once.h>
+#include <sys/intr.h>
+
+#include <machine/vectors.h>
+
+#include <uvm/uvm_extern.h>
+
+#ifdef __HAVE_M68K_INTR_VECTORED
+#ifndef MACHINE_USERVEC_START
+#define MACHINE_USERVEC_START VECI_USRVEC_START
+#endif
+
+#define NVECHANDS (NVECTORS - MACHINE_USERVEC_START)
+
+#ifndef INTR_FREEVEC
+#define INTR_FREEVEC badtrap
+#endif
+
+extern char INTR_FREEVEC[];
+extern char intrstub_vectored[];
+#endif /* __HAVE_M68K_INTR_VECTORED */
+
+/* A dummy event counter where interrupt stats go to die. */
+static struct evcnt bitbucket;
+
+extern int intrcnt[]; /* XXX old-style statistics */
+
+int idepth;
+
+static struct m68k_intrhand_list m68k_intrhands_autovec[NAUTOVECTORS];
+#ifdef __HAVE_M68K_INTR_VECTORED
+static struct m68k_intrhand *m68k_intrhands_vectored[NVECHANDS];
+#endif
+
+const uint16_t ipl2psl_table[NIPL] = {
+ [IPL_NONE] = PSL_S | PSL_IPL0,
+ [IPL_SOFTBIO] = PSL_S | MACHINE_PSL_IPL_SOFTBIO,
+ [IPL_SOFTCLOCK] = PSL_S | MACHINE_PSL_IPL_SOFTCLOCK,
+ [IPL_SOFTNET] = PSL_S | MACHINE_PSL_IPL_SOFTNET,
+ [IPL_SOFTSERIAL] = PSL_S | MACHINE_PSL_IPL_SOFTSERIAL,
+ [IPL_VM] = PSL_S | MACHINE_PSL_IPL_VM,
+ [IPL_SCHED] = PSL_S | MACHINE_PSL_IPL_SCHED,
+ [IPL_HIGH] = PSL_S | PSL_IPL7,
+};
+
+static struct m68k_intrhand *
+m68k_ih_stdalloc(int km_flag)
+{
+ return kmem_zalloc(sizeof(struct m68k_intrhand), km_flag);
+}
+
+static void
+m68k_ih_stdfree(struct m68k_intrhand *ih)
+{
+ kmem_free(ih, sizeof(*ih));
+}
+
+static const struct m68k_ih_allocfuncs m68k_ih_stdallocfuncs = {
+ .alloc = m68k_ih_stdalloc,
+ .free = m68k_ih_stdfree,
+};
+
+static const struct m68k_ih_allocfuncs *ih_allocfuncs;
+
+static struct m68k_intrhand *
+m68k_ih_alloc(void)
+{
+ KASSERT(ih_allocfuncs != NULL);
+ return ih_allocfuncs->alloc(KM_SLEEP);
+}
+
+static void
+m68k_ih_free(struct m68k_intrhand *ih)
+{
+ KASSERT(ih_allocfuncs != NULL);
+ ih_allocfuncs->free(ih);
+}
+
+#ifdef __HAVE_M68K_INTR_VECTORED
+
+#define INTRVEC_SLOT(vec) \
+ (&m68k_intrhands_vectored[(vec) - MACHINE_USERVEC_START])
+
+#define m68k_intrvec_handler(vec) (*INTRVEC_SLOT(vec))
+
+static bool
+m68k_intrvec_add(struct m68k_intrhand *ih)
+{
+ if (ih->ih_vec < MACHINE_USERVEC_START || ih->ih_vec >= NVECTORS) {
+ aprint_error("%s: vector=0x%x (invalid)\n", __func__,
+ ih->ih_vec);
+ return false;
+ }
+
+ struct m68k_intrhand **slot =
+ &m68k_intrhands_vectored[ih->ih_vec - MACHINE_USERVEC_START];
+
+ if (*slot != NULL) {
+ aprint_error("%s: vector=0x%x (in use)\n", __func__,
+ ih->ih_vec);
+ return false;
+ }
+
+ if (vec_get_entry(ih->ih_vec) != INTR_FREEVEC) {
+ aprint_error("%s: vector=0x%x (unavailable)\n", __func__,
+ ih->ih_vec);
+ return false;
+ }
+
+ *slot = ih;
+ vec_set_entry(ih->ih_vec, intrstub_vectored);
+ return true;
+}
+
+static void
+m68k_intrvec_remove(struct m68k_intrhand *ih)
+{
+ KASSERT(ih->ih_vec >= MACHINE_USERVEC_START);
+ KASSERT(ih->ih_vec < NVECTORS);
+
+ struct m68k_intrhand **slot =
+ &m68k_intrhands_vectored[ih->ih_vec - MACHINE_USERVEC_START];
+
+ KASSERT(*slot == ih);
+ KASSERT(vec_get_entry(ih->ih_vec) == intrstub_vectored);
+
+ vec_set_entry(ih->ih_vec, INTR_FREEVEC);
+ *slot = NULL;
+}
+
+#endif /* __HAVE_M68K_INTR_VECTORED */
+
+/*
+ * m68k_intr_init --
+ * Initialize the interrupt subsystem.
+ */
+void
+m68k_intr_init(const struct m68k_ih_allocfuncs *allocfuncs)
+{
+ int i;
+
+ KASSERT(ih_allocfuncs == NULL);
+ if (allocfuncs == NULL) {
+ ih_allocfuncs = &m68k_ih_stdallocfuncs;
+ } else {
+ ih_allocfuncs = allocfuncs;
+ }
+
+ for (i = 0; i < NAUTOVECTORS; i++) {
+ LIST_INIT(&m68k_intrhands_autovec[i]);
+ }
+}
+
+/*
+ * m68k_intr_establish --
+ * Establish an interrupt handler at the specified vector.
+ * XXX We don't do anything with isrpri yet.
+ * XXX We don't do anything with the flags yet.
+ */
+void *
+m68k_intr_establish(int (*func)(void *), void *arg, struct evcnt *ev,
+ int vec, int ipl, int isrpri __unused, int flags __unused)
+{
+ struct m68k_intrhand *ih;
+ int s;
+
+ /*
+ * If a platform doesn't want special behavior, we don't
+ * require them to call m68k_intr_init(); we just handle
+ * it here.
+ *
+ * XXX m68k_intr_init() might be called really early, so
+ * XXX can't use a once control.
+ */
+ if (__predict_false(ih_allocfuncs == NULL)) {
+ m68k_intr_init(NULL);
+ }
+
+ /* These are m68k IPLs, not IPL_* values. */
+ if (ipl < 0 || ipl > 7) {
+ return NULL;
+ }
+
+#ifdef __HAVE_M68K_INTR_VECTORED
+ KASSERT(vec >= 0);
+ KASSERT(vec < NVECTORS);
+#else
+ KASSERT(vec == 0);
+#endif /* __HAVE_M68K_INTR_VECTORED */
+
+ ih = m68k_ih_alloc();
+ ih->ih_func = func;
+ ih->ih_arg = arg;
+ ih->ih_vec = vec;
+ ih->ih_ipl = ipl;
+ if ((ih->ih_evcnt = ev) == NULL) {
+ ih->ih_evcnt = &bitbucket;
+ }
+
+#ifdef __HAVE_M68K_INTR_VECTORED
+ if (vec != 0) {
+ if (vec_get_entry(vec) != INTR_FREEVEC) {
+ m68k_ih_free(ih);
+ return NULL;
+ }
+ if (! m68k_intrvec_add(ih)) {
+ m68k_ih_free(ih);
+ return NULL;
+ }
+ return ih;
+ }
+#endif
+
+ s = splhigh();
+ LIST_INSERT_HEAD(&m68k_intrhands_autovec[ipl], ih, ih_link);
+ splx(s);
+
+ return ih;
+}
+
+/*
+ * m68k_intr_disestablish --
+ * Remove an interrupt handler. Returns true if the handler
+ * list for this vector is now empty.
+ */
+bool
+m68k_intr_disestablish(void *v)
+{
+ struct m68k_intrhand *ih = v;
+ int s;
+ bool empty;
+
+#ifdef __HAVE_M68K_INTR_VECTORED
+ if (ih->ih_vec != 0) {
+ KASSERT(vec_get_entry(ih->ih_vec) == intrstub_vectored);
+ m68k_intrvec_remove(ih);
+ empty = true;
+ } else
+#endif
+ {
+ s = splhigh();
+ LIST_REMOVE(ih, ih_link);
+ empty = LIST_EMPTY(&m68k_intrhands_autovec[ih->ih_ipl]);
+ splx(s);
+ }
+
+ return empty;
+}
+
+void m68k_intr_autovec(struct clockframe);
+
+/*
+ * m68k_intr_autovec --
+ * Run the interrupt handlers for an auto-vectored interrupt.
+ * Called from the assembly glue in m68k_intr_stubs.s
+ */
+void
+m68k_intr_autovec(struct clockframe frame)
+{
+ const int ipl = VECO_TO_VECI(frame.cf_vo & 0xfff) - VECI_INTRAV0;
+ struct m68k_intrhand *ih;
+ bool rv = false;
+
+ idepth++;
+
+ intrcnt[ipl]++; /* XXX */
+ curcpu()->ci_data.cpu_nintr++;
+
+ LIST_FOREACH(ih, &m68k_intrhands_autovec[ipl], ih_link) {
+ void *arg = ih->ih_arg ? ih->ih_arg : &frame;
+ if (ih->ih_func(arg)) {
+ ih->ih_evcnt->ev_count++;
+ rv = true;
+ }
+ }
+ if (!rv) {
+ printf("Spurious interrupt on IPL %d\n", ipl);
+ }
+
+ idepth--;
+
+ ATOMIC_CAS_CHECK(&frame);
+}
+
+#ifdef __HAVE_M68K_INTR_VECTORED
+void m68k_intr_vectored(struct clockframe);
+
+/*
+ * m68k_intr_vectored --
+ * Run a vectored interrupt handler.
+ * Called from the assembly glue in m68k_intr_stubs.s
+ */
+void
+m68k_intr_vectored(struct clockframe frame)
+{
+ const int vec = VECO_TO_VECI(frame.cf_vo & 0xfff);
+ const int ipl = (getsr() >> 8) & 7;
+ struct m68k_intrhand *ih;
+
+ idepth++;
+
+ intrcnt[ipl]++; /* XXX */
+ curcpu()->ci_data.cpu_nintr++;
+
+#ifdef DIAGNOSTIC
+ if (vec < MACHINE_USERVEC_START || vec >= NVECTORS) {
+ printf("%s: vector=0x%x (invalid)\n", __func__, vec);
+ goto out;
+ }
+#endif
+ ih = m68k_intrvec_handler(vec);
+ if (ih == NULL) {
+ printf("%s: vector=0x%x (no handler?)\n", __func__, vec);
+ vec_set_entry(vec, INTR_FREEVEC);
+ }
+
+ if ((*ih->ih_func)(ih->ih_arg ? ih->ih_arg : &frame) == 0) {
+ printf("Spurious interrupt on vector=0x%0x IPL %d\n",
+ vec, ipl);
+ }
+#ifdef DIAGNOSTIC
+ out:
+#endif
+ idepth--;
+
+ ATOMIC_CAS_CHECK(&frame);
+}
+#endif /* __HAVE_M68K_INTR_VECTORED */
Index: src/sys/arch/m68k/m68k/m68k_intr_stubs.s
diff -u /dev/null src/sys/arch/m68k/m68k/m68k_intr_stubs.s:1.1
--- /dev/null Sun Jan 14 22:32:32 2024
+++ src/sys/arch/m68k/m68k/m68k_intr_stubs.s Sun Jan 14 22:32:32 2024
@@ -0,0 +1,73 @@
+/* $NetBSD: m68k_intr_stubs.s,v 1.1 2024/01/14 22:32:32 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1980, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Utah $Hdr: locore.s 1.66 92/12/22$
+ * @(#)locore.s 8.6 (Berkeley) 5/27/94
+ */
+
+#include <machine/asm.h>
+
+#include "assym.h"
+
+ .file "m68k_intr_stubs.s"
+ .text
+
+#ifdef __ELF__
+#define INTRSTUB_ALIGN .align 4
+#else
+#define INTRSTUB_ALIGN .align 2
+#endif
+
+/*
+ * Vector stub for auto-vectored interrupts. Calls the dispatch
+ * routine with the frame BY VALUE (saves a few instructions).
+ */
+ INTRSTUB_ALIGN
+ENTRY_NOPROFILE(intrstub_autovec)
+ INTERRUPT_SAVEREG
+ jbsr _C_LABEL(m68k_intr_autovec)
+ INTERRUPT_RESTOREREG
+ jra _ASM_LABEL(rei)
+
+#ifdef __HAVE_M68K_INTR_VECTORED
+/*
+ * Vector stub for vectored interrupts. Same stack situation as above.
+ */
+ INTRSTUB_ALIGN
+ENTRY_NOPROFILE(intrstub_vectored)
+ INTERRUPT_SAVEREG
+ jbsr _C_LABEL(m68k_intr_vectored)
+ INTERRUPT_RESTOREREG
+ jra _ASM_LABEL(rei)
+#endif /* __HAVE_M68K_INTR_VECTORED */