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 */

Reply via email to