intr.c revision 129198
1/* $NetBSD: intr.c,v 1.12 2003/07/15 00:24:41 lukem Exp $ */ 2 3/* 4 * Copyright (c) 2004 Olivier Houchard. 5 * Copyright (c) 1994-1998 Mark Brinicombe. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Mark Brinicombe 19 * for the NetBSD Project. 20 * 4. The name of the company nor the name of the author may be used to 21 * endorse or promote products derived from this software without specific 22 * prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * Soft interrupt and other generic interrupt functions. 37 */ 38 39#include <sys/cdefs.h> 40__FBSDID("$FreeBSD: head/sys/arm/arm/intr.c 129198 2004-05-14 11:46:45Z cognet $"); 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/syslog.h> 44#include <sys/malloc.h> 45#include <sys/bus.h> 46#include <sys/interrupt.h> 47#include <sys/conf.h> 48#include <machine/atomic.h> 49#include <machine/intr.h> 50#include <machine/cpu.h> 51 52int current_spl_level = _SPL_SERIAL; 53 54u_int spl_masks[_SPL_LEVELS + 1]; 55u_int spl_smasks[_SPL_LEVELS]; 56extern u_int irqmasks[]; 57 58#define NIRQ 0x20 /* XXX */ 59struct ithd *ithreads[NIRQ]; 60void 61set_splmasks() 62{ 63 int loop; 64 65 for (loop = 0; loop < _SPL_LEVELS; ++loop) { 66 spl_masks[loop] = 0xffffffff; 67 spl_smasks[loop] = 1; 68 } 69 70 spl_masks[_SPL_NET] = irqmasks[IPL_NET]; 71 spl_masks[_SPL_SOFTSERIAL] = irqmasks[IPL_TTY]; 72 spl_masks[_SPL_TTY] = irqmasks[IPL_TTY]; 73 spl_masks[_SPL_VM] = irqmasks[IPL_VM]; 74 spl_masks[_SPL_AUDIO] = irqmasks[IPL_AUDIO]; 75 spl_masks[_SPL_CLOCK] = irqmasks[IPL_CLOCK]; 76#ifdef IPL_STATCLOCK 77 spl_masks[_SPL_STATCLOCK] = irqmasks[IPL_STATCLOCK]; 78#else 79 spl_masks[_SPL_STATCLOCK] = irqmasks[IPL_CLOCK]; 80#endif 81 spl_masks[_SPL_HIGH] = irqmasks[IPL_HIGH]; 82 spl_masks[_SPL_SERIAL] = irqmasks[IPL_SERIAL]; 83 spl_masks[_SPL_LEVELS] = 0; 84 85 spl_smasks[_SPL_0] = 0xffffffff; 86 for (loop = 0; loop < _SPL_SOFTSERIAL; ++loop) 87 spl_smasks[loop] |= SOFTIRQ_BIT(SOFTIRQ_SERIAL); 88 for (loop = 0; loop < _SPL_SOFTNET; ++loop) 89 spl_smasks[loop] |= SOFTIRQ_BIT(SOFTIRQ_NET); 90 for (loop = 0; loop < _SPL_SOFTCLOCK; ++loop) 91 spl_smasks[loop] |= SOFTIRQ_BIT(SOFTIRQ_CLOCK); 92} 93 94void arm_setup_irqhandler(const char *name, void (*hand)(void*), void *arg, 95 int irq, int flags, void **cookiep) 96{ 97 struct ithd *cur_ith; 98 int error; 99 100 if (irq < 0 || irq >= NIRQ) 101 return; 102 cur_ith = ithreads[irq]; 103 if (cur_ith == NULL) { 104 error = ithread_create(&cur_ith, irq, 0, NULL, NULL, "intr%d:", 105 irq); 106 if (error) 107 return; 108 ithreads[irq] = cur_ith; 109 } 110 ithread_add_handler(cur_ith, name, hand, arg, ithread_priority(flags), 111 flags, cookiep); 112} 113 114void dosoftints(void); 115void 116dosoftints(void) 117{ 118} 119 120void 121arm_handler_execute(void *); 122void 123arm_handler_execute(void *irq) 124{ 125 struct ithd *ithd; 126 int i; 127 int irqnb = (int)irq; 128 struct intrhand *ih; 129 130 for (i = 0; i < NIRQ; i++) { 131 if (1 << i & irqnb) { 132 ithd = ithreads[i]; 133 if (!ithd) /* FUCK */ 134 return; 135 ih = TAILQ_FIRST(&ithd->it_handlers); 136 if (ih && ih->ih_flags & IH_FAST) { 137 TAILQ_FOREACH(ih, &ithd->it_handlers, 138 ih_next) { 139 ih->ih_handler(ih->ih_argument); 140 /* 141 * XXX: what about the irq frame if 142 * the arg is NULL ? 143 */ 144 } 145 } else if (ih) { 146 ithread_schedule(ithd, !cold); 147 } 148 } 149 } 150} 151