/*-
* 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.
*/
#ifdef __HAVE_LEGACY_INTRCNT
#define m68k_count_intr(x) \
do { \
extern u_int intrcnt[]; \
intrcnt[(x)]++; \
curcpu()->ci_data.cpu_nintr++; \
} while (/*CONSTCOND*/0)
#else
/*
* This is exposed here so that platform-specific interrupt handlers
* can access it.
*/
extern struct evcnt m68k_intr_evcnt[];
#define m68k_count_intr(x) \
do { \
/* 32-bit counter should be sufficient for m68k. */ \
m68k_intr_evcnt[(x)].ev_count32++; \
curcpu()->ci_data.cpu_nintr++; \
} while (/*CONSTCOND*/0)
#endif /* __HAVE_LEGACY_INTRCNT */
/*
* 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 shareable. 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 *);