1*c992d008Svisa /* $OpenBSD: intr.h,v 1.18 2019/09/05 05:31:38 visa Exp $ */ 2cef8ac4dSmiod 3cef8ac4dSmiod /* 4cef8ac4dSmiod * Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) 5cef8ac4dSmiod * 6cef8ac4dSmiod * Redistribution and use in source and binary forms, with or without 7cef8ac4dSmiod * modification, are permitted provided that the following conditions 8cef8ac4dSmiod * are met: 9cef8ac4dSmiod * 1. Redistributions of source code must retain the above copyright 10cef8ac4dSmiod * notice, this list of conditions and the following disclaimer. 11cef8ac4dSmiod * 2. Redistributions in binary form must reproduce the above copyright 12cef8ac4dSmiod * notice, this list of conditions and the following disclaimer in the 13cef8ac4dSmiod * documentation and/or other materials provided with the distribution. 14cef8ac4dSmiod * 15cef8ac4dSmiod * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16cef8ac4dSmiod * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17cef8ac4dSmiod * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18cef8ac4dSmiod * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19cef8ac4dSmiod * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20cef8ac4dSmiod * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21cef8ac4dSmiod * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22cef8ac4dSmiod * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23cef8ac4dSmiod * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24cef8ac4dSmiod * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25cef8ac4dSmiod * SUCH DAMAGE. 26cef8ac4dSmiod * 27cef8ac4dSmiod */ 28cef8ac4dSmiod 29cef8ac4dSmiod #ifndef _MACHINE_INTR_H_ 30cef8ac4dSmiod #define _MACHINE_INTR_H_ 31cef8ac4dSmiod 32cef8ac4dSmiod /* 33cef8ac4dSmiod * The interrupt level ipl is a logical level; per-platform interrupt 34cef8ac4dSmiod * code will turn it into the appropriate hardware interrupt masks 35cef8ac4dSmiod * values. 36cef8ac4dSmiod * 37cef8ac4dSmiod * Interrupt sources on the CPU are kept enabled regardless of the 38cef8ac4dSmiod * current ipl value; individual hardware sources interrupting while 39cef8ac4dSmiod * logically masked are masked on the fly, remembered as pending, and 40cef8ac4dSmiod * unmasked at the first splx() opportunity. 41cef8ac4dSmiod * 42cef8ac4dSmiod * An exception to this rule is the clock interrupt. Clock interrupts 43cef8ac4dSmiod * are always allowed to happen, but will (of course!) not be serviced 44cef8ac4dSmiod * if logically masked. The reason for this is that clocks usually sit on 45cef8ac4dSmiod * INT5 and cannot be easily masked if external hardware masking is used. 46cef8ac4dSmiod */ 47cef8ac4dSmiod 48cef8ac4dSmiod /* Interrupt priority `levels'; not mutually exclusive. */ 49cef8ac4dSmiod #define IPL_NONE 0 /* nothing */ 50cef8ac4dSmiod #define IPL_SOFTINT 1 /* soft interrupts */ 51ba0d7474Svisa #define IPL_SOFTCLOCK 1 /* soft clock interrupts */ 52ba0d7474Svisa #define IPL_SOFTNET 2 /* soft network interrupts */ 53ba0d7474Svisa #define IPL_SOFTTTY 3 /* soft terminal interrupts */ 54ba0d7474Svisa #define IPL_SOFTHIGH IPL_SOFTTTY /* highest level of soft interrupts */ 55ba0d7474Svisa #define IPL_BIO 4 /* block I/O */ 56cef8ac4dSmiod #define IPL_AUDIO IPL_BIO 57ba0d7474Svisa #define IPL_NET 5 /* network */ 58ba0d7474Svisa #define IPL_TTY 6 /* terminal */ 59ba0d7474Svisa #define IPL_VM 7 /* memory allocation */ 60ba0d7474Svisa #define IPL_CLOCK 8 /* clock */ 61c73f1fefSpirofti #define IPL_STATCLOCK IPL_CLOCK 62ba0d7474Svisa #define IPL_SCHED 9 /* everything */ 63ba0d7474Svisa #define IPL_HIGH 9 /* everything */ 64ba0d7474Svisa #define IPL_IPI 10 /* interprocessor interrupt */ 65ba0d7474Svisa #define NIPLS 11 /* number of levels */ 66cef8ac4dSmiod 67706f15edSdlg #define IPL_MPFLOOR IPL_TTY 68706f15edSdlg 69ee8a2a3cSkettenis /* Interrupt priority 'flags'. */ 708aa1a2d2Svisa #define IPL_MPSAFE 0x100 71ee8a2a3cSkettenis 72cef8ac4dSmiod /* Interrupt sharing types. */ 73cef8ac4dSmiod #define IST_NONE 0 /* none */ 74cef8ac4dSmiod #define IST_PULSE 1 /* pulsed */ 75cef8ac4dSmiod #define IST_EDGE 2 /* edge-triggered */ 76cef8ac4dSmiod #define IST_LEVEL 3 /* level-triggered */ 77cef8ac4dSmiod 78cef8ac4dSmiod #define SINTBIT(q) (q) 79cef8ac4dSmiod #define SINTMASK(q) (1 << SINTBIT(q)) 80cef8ac4dSmiod 81cef8ac4dSmiod /* Soft interrupt masks. */ 82cef8ac4dSmiod 83ba0d7474Svisa #define SI_SOFTCLOCK 0 /* for IPL_SOFTCLOCK */ 84ba0d7474Svisa #define SI_SOFTNET 1 /* for IPL_SOFTNET */ 85ba0d7474Svisa #define SI_SOFTTTY 2 /* for IPL_SOFTTTY */ 86cef8ac4dSmiod 87ba0d7474Svisa #define SI_NQUEUES 3 88cef8ac4dSmiod 89cef8ac4dSmiod #ifndef _LOCORE 90cef8ac4dSmiod 9165976d5fSmpi #include <sys/mutex.h> 92cef8ac4dSmiod #include <sys/queue.h> 93cef8ac4dSmiod 94cef8ac4dSmiod struct soft_intrhand { 95cef8ac4dSmiod TAILQ_ENTRY(soft_intrhand) sih_list; 96cef8ac4dSmiod void (*sih_func)(void *); 97cef8ac4dSmiod void *sih_arg; 98cef8ac4dSmiod struct soft_intrq *sih_siq; 99cef8ac4dSmiod int sih_pending; 100cef8ac4dSmiod }; 101cef8ac4dSmiod 102cef8ac4dSmiod struct soft_intrq { 103cef8ac4dSmiod TAILQ_HEAD(, soft_intrhand) siq_list; 104cef8ac4dSmiod int siq_si; 105cef8ac4dSmiod struct mutex siq_mtx; 106cef8ac4dSmiod }; 107cef8ac4dSmiod 108cef8ac4dSmiod void softintr_disestablish(void *); 109cef8ac4dSmiod void softintr_dispatch(int); 110cef8ac4dSmiod void *softintr_establish(int, void (*)(void *), void *); 111cef8ac4dSmiod void softintr_init(void); 112cef8ac4dSmiod void softintr_schedule(void *); 113cef8ac4dSmiod 114cef8ac4dSmiod #define splbio() splraise(IPL_BIO) 115cef8ac4dSmiod #define splnet() splraise(IPL_NET) 116cef8ac4dSmiod #define spltty() splraise(IPL_TTY) 117cef8ac4dSmiod #define splaudio() splraise(IPL_AUDIO) 118cef8ac4dSmiod #define splclock() splraise(IPL_CLOCK) 119cef8ac4dSmiod #define splvm() splraise(IPL_VM) 120cef8ac4dSmiod #define splhigh() splraise(IPL_HIGH) 121cef8ac4dSmiod 122ba0d7474Svisa #define splsoftclock() splraise(IPL_SOFTCLOCK) 123ba0d7474Svisa #define splsoftnet() splraise(IPL_SOFTNET) 124cef8ac4dSmiod #define splstatclock() splhigh() 125cef8ac4dSmiod 126cef8ac4dSmiod #define splsched() splhigh() 127cef8ac4dSmiod #define spl0() spllower(0) 128cef8ac4dSmiod 129cef8ac4dSmiod void splinit(void); 130cef8ac4dSmiod 131*c992d008Svisa #ifdef DIAGNOSTIC 132*c992d008Svisa /* 133*c992d008Svisa * Although this function is implemented in MI code, it must be in this MD 134*c992d008Svisa * header because we don't want this header to include MI includes. 135*c992d008Svisa */ 136*c992d008Svisa void splassert_fail(int, int, const char *); 137*c992d008Svisa extern int splassert_ctl; 138*c992d008Svisa void splassert_check(int, const char *); 139*c992d008Svisa #define splassert(__wantipl) do { \ 140*c992d008Svisa if (splassert_ctl > 0) { \ 141*c992d008Svisa splassert_check(__wantipl, __func__); \ 142*c992d008Svisa } \ 143*c992d008Svisa } while (0) 144*c992d008Svisa #define splsoftassert(wantipl) splassert(wantipl) 145*c992d008Svisa #else 146cef8ac4dSmiod #define splassert(X) 147cef8ac4dSmiod #define splsoftassert(X) 148*c992d008Svisa #endif 149cef8ac4dSmiod 150aff9d062Svisa void register_splx_handler(void (*)(int)); 151cef8ac4dSmiod int splraise(int); 152cef8ac4dSmiod void splx(int); 153cef8ac4dSmiod int spllower(int); 154cef8ac4dSmiod 155cef8ac4dSmiod /* 156cef8ac4dSmiod * Interrupt control struct used by interrupt dispatchers 157cef8ac4dSmiod * to hold interrupt handler info. 158cef8ac4dSmiod */ 159cef8ac4dSmiod 160cef8ac4dSmiod #include <sys/evcount.h> 161cef8ac4dSmiod 162cef8ac4dSmiod struct intrhand { 163cef8ac4dSmiod struct intrhand *ih_next; 164cef8ac4dSmiod int (*ih_fun)(void *); 165cef8ac4dSmiod void *ih_arg; 166cef8ac4dSmiod int ih_level; 167cef8ac4dSmiod int ih_irq; 1685fa8ecb3Svisa int ih_flags; 1695fa8ecb3Svisa #define IH_MPSAFE 0x01 170cef8ac4dSmiod struct evcount ih_count; 171cef8ac4dSmiod }; 172cef8ac4dSmiod 17327262a1bSkettenis void intr_barrier(void *); 17427262a1bSkettenis 175cef8ac4dSmiod /* 176cef8ac4dSmiod * Low level interrupt dispatcher registration data. 177cef8ac4dSmiod */ 178cef8ac4dSmiod 179cef8ac4dSmiod /* Schedule priorities for base interrupts (CPU) */ 180e8637625Svisa #define INTPRI_IPI 0 181e8637625Svisa #define INTPRI_CLOCK 1 182cef8ac4dSmiod /* other values are system-specific */ 183cef8ac4dSmiod 184cef8ac4dSmiod #define NLOWINT 4 /* Number of low level registrations possible */ 185cef8ac4dSmiod 186cef8ac4dSmiod extern uint32_t idle_mask; 187cef8ac4dSmiod 188b43ebd13Smpi struct trapframe; 189b43ebd13Smpi void set_intr(int, uint32_t, uint32_t(*)(uint32_t, struct trapframe *)); 190cef8ac4dSmiod 191cef8ac4dSmiod uint32_t updateimask(uint32_t); 192cef8ac4dSmiod void dosoftint(void); 193cef8ac4dSmiod 19439de0dfdSvisa #ifdef MULTIPROCESSOR 19539de0dfdSvisa extern uint32_t ipi_mask; 19639de0dfdSvisa #define ENABLEIPI() updateimask(~ipi_mask) 19739de0dfdSvisa #endif 19839de0dfdSvisa 1995fa8ecb3Svisa struct pic { 2005fa8ecb3Svisa void (*pic_eoi)(int); 2015fa8ecb3Svisa void (*pic_mask)(int); 2025fa8ecb3Svisa void (*pic_unmask)(int); 2035fa8ecb3Svisa }; 2045fa8ecb3Svisa 2055fa8ecb3Svisa #ifdef CPU_LOONGSON3 2065fa8ecb3Svisa 2075fa8ecb3Svisa void loongson3_intr_init(void); 2085fa8ecb3Svisa void *loongson3_intr_establish(int, int, int (*)(void *), void*, 2095fa8ecb3Svisa const char *); 2105fa8ecb3Svisa void loongson3_intr_disestablish(void *); 2115fa8ecb3Svisa void *loongson3_ht_intr_establish(int, int, int (*)(void *), void*, 2125fa8ecb3Svisa const char *); 2135fa8ecb3Svisa void loongson3_ht_intr_disestablish(void *); 2145fa8ecb3Svisa 2155fa8ecb3Svisa void loongson3_register_ht_pic(const struct pic *); 2165fa8ecb3Svisa 2175fa8ecb3Svisa #endif /* CPU_LOONGSON3 */ 2185fa8ecb3Svisa 219cef8ac4dSmiod #endif /* _LOCORE */ 220cef8ac4dSmiod 221cef8ac4dSmiod #endif /* _MACHINE_INTR_H_ */ 222