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