1 1.10 tsutsui /* $NetBSD: interrupt.c,v 1.10 2023/08/30 17:10:17 tsutsui Exp $ */ 2 1.1 tsutsui /* $OpenBSD: trap.c,v 1.22 1999/05/24 23:08:59 jason Exp $ */ 3 1.1 tsutsui 4 1.1 tsutsui /* 5 1.7 rmind * Copyright (c) 1988 University of Utah. 6 1.1 tsutsui * Copyright (c) 1992, 1993 7 1.1 tsutsui * The Regents of the University of California. All rights reserved. 8 1.1 tsutsui * 9 1.1 tsutsui * This code is derived from software contributed to Berkeley by 10 1.1 tsutsui * the Systems Programming Group of the University of Utah Computer 11 1.1 tsutsui * Science Department and Ralph Campbell. 12 1.1 tsutsui * 13 1.1 tsutsui * Redistribution and use in source and binary forms, with or without 14 1.1 tsutsui * modification, are permitted provided that the following conditions 15 1.1 tsutsui * are met: 16 1.1 tsutsui * 1. Redistributions of source code must retain the above copyright 17 1.1 tsutsui * notice, this list of conditions and the following disclaimer. 18 1.1 tsutsui * 2. Redistributions in binary form must reproduce the above copyright 19 1.1 tsutsui * notice, this list of conditions and the following disclaimer in the 20 1.1 tsutsui * documentation and/or other materials provided with the distribution. 21 1.1 tsutsui * 3. Neither the name of the University nor the names of its contributors 22 1.1 tsutsui * may be used to endorse or promote products derived from this software 23 1.1 tsutsui * without specific prior written permission. 24 1.1 tsutsui * 25 1.1 tsutsui * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 1.1 tsutsui * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 1.1 tsutsui * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 1.1 tsutsui * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 1.1 tsutsui * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 1.1 tsutsui * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 1.1 tsutsui * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 1.1 tsutsui * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 1.1 tsutsui * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 1.1 tsutsui * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 1.1 tsutsui * SUCH DAMAGE. 36 1.1 tsutsui * 37 1.1 tsutsui * from: Utah Hdr: trap.c 1.32 91/04/06 38 1.1 tsutsui * 39 1.1 tsutsui * @(#)trap.c 8.5 (Berkeley) 1/11/94 40 1.1 tsutsui */ 41 1.1 tsutsui 42 1.1 tsutsui #include <sys/cdefs.h> 43 1.10 tsutsui __KERNEL_RCSID(0, "$NetBSD: interrupt.c,v 1.10 2023/08/30 17:10:17 tsutsui Exp $"); 44 1.1 tsutsui 45 1.1 tsutsui #include <sys/param.h> 46 1.1 tsutsui #include <sys/systm.h> 47 1.1 tsutsui #include <sys/kernel.h> 48 1.3 ad #include <sys/intr.h> 49 1.3 ad #include <sys/cpu.h> 50 1.1 tsutsui 51 1.1 tsutsui #include <mips/locore.h> 52 1.1 tsutsui 53 1.1 tsutsui #include <machine/autoconf.h> 54 1.1 tsutsui #include <machine/pio.h> 55 1.1 tsutsui 56 1.1 tsutsui #include <arc/arc/timervar.h> 57 1.1 tsutsui #include <arc/jazz/pica.h> 58 1.1 tsutsui #include <arc/jazz/rd94.h> 59 1.1 tsutsui 60 1.1 tsutsui struct cpu_inttab { 61 1.1 tsutsui uint32_t int_mask; 62 1.1 tsutsui uint32_t (*int_hand)(uint32_t, struct clockframe *); 63 1.1 tsutsui }; 64 1.1 tsutsui static struct cpu_inttab cpu_int_tab[ARC_NINTPRI]; 65 1.1 tsutsui 66 1.1 tsutsui uint32_t cpu_int_mask; /* External cpu interrupt mask */ 67 1.1 tsutsui 68 1.1 tsutsui /* 69 1.1 tsutsui * Set up handler for external interrupt events. 70 1.1 tsutsui * Events are checked in priority order. 71 1.1 tsutsui */ 72 1.1 tsutsui void 73 1.1 tsutsui arc_set_intr(uint32_t mask, uint32_t (*int_hand)(uint32_t, struct clockframe *), 74 1.1 tsutsui int prio) 75 1.1 tsutsui { 76 1.1 tsutsui 77 1.1 tsutsui if (prio >= ARC_NINTPRI) 78 1.1 tsutsui panic("arc_set_intr: too high priority"); 79 1.1 tsutsui 80 1.1 tsutsui if (cpu_int_tab[prio].int_mask != 0 && 81 1.1 tsutsui (cpu_int_tab[prio].int_mask != mask || 82 1.1 tsutsui cpu_int_tab[prio].int_hand != int_hand)) { 83 1.1 tsutsui panic("set_intr: int already set"); 84 1.1 tsutsui } 85 1.1 tsutsui 86 1.1 tsutsui cpu_int_tab[prio].int_hand = int_hand; 87 1.1 tsutsui cpu_int_tab[prio].int_mask = mask; 88 1.1 tsutsui cpu_int_mask |= mask >> 10; 89 1.1 tsutsui } 90 1.1 tsutsui 91 1.1 tsutsui /* 92 1.1 tsutsui * Handle an interrupt. 93 1.1 tsutsui */ 94 1.1 tsutsui void 95 1.8 matt cpu_intr(int ppl, vaddr_t pc, uint32_t status) 96 1.1 tsutsui { 97 1.8 matt struct cpu_inttab *inttab; 98 1.1 tsutsui struct clockframe cf; 99 1.8 matt uint32_t ipending; 100 1.1 tsutsui u_int i; 101 1.8 matt int ipl; 102 1.1 tsutsui 103 1.8 matt curcpu()->ci_data.cpu_nintr++; 104 1.1 tsutsui 105 1.1 tsutsui cf.pc = pc; 106 1.1 tsutsui cf.sr = status; 107 1.8 matt cf.intr = (curcpu()->ci_idepth > 1); 108 1.1 tsutsui 109 1.8 matt while (ppl < (ipl = splintr(&ipending))) { 110 1.8 matt /* check MIPS3 internal clock interrupt */ 111 1.8 matt if (ipending & MIPS_INT_MASK_5) { 112 1.8 matt /* 113 1.8 matt * Writing a value to the Compare register, as a side 114 1.8 matt * effect, clears the timer interrupt request. 115 1.8 matt */ 116 1.8 matt mips3_cp0_compare_write(0); 117 1.8 matt } 118 1.8 matt 119 1.1 tsutsui /* 120 1.8 matt * If there is an independent timer interrupt handler, 121 1.8 matt * call it first. 122 1.1 tsutsui */ 123 1.8 matt inttab = &cpu_int_tab[ARC_INTPRI_TIMER_INT]; 124 1.8 matt if (inttab->int_mask & ipending) { 125 1.8 matt (*inttab->int_hand)(ipending, &cf); 126 1.8 matt } 127 1.1 tsutsui 128 1.8 matt /* 129 1.8 matt * Check off all other enabled interrupts. 130 1.8 matt * Called handlers return mask of interrupts to be reenabled. 131 1.8 matt */ 132 1.8 matt for (inttab++, i = ARC_INTPRI_TIMER_INT + 1; 133 1.8 matt i < ARC_NINTPRI; 134 1.8 matt inttab++, i++) { 135 1.8 matt if (inttab->int_mask & ipending) { 136 1.8 matt (*inttab->int_hand)(ipending, &cf); 137 1.8 matt } 138 1.1 tsutsui } 139 1.8 matt (void)splhigh(); 140 1.1 tsutsui } 141 1.1 tsutsui } 142