irq_dispatch.S revision 1.4
1/* $NetBSD: irq_dispatch.S,v 1.4 2003/10/26 11:34:29 scw Exp $ */ 2 3/* 4 * Copyright (c) 2002 Fujitsu Component Limited 5 * Copyright (c) 2002 Genetec Corporation 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. Neither the name of The Fujitsu Component Limited nor the name of 17 * Genetec corporation may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC 21 * CORPORATION ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL FUJITSU COMPONENT LIMITED OR GENETEC 25 * CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35/* 36 * Copyright (c) 2002, 2003 Wasabi Systems, Inc. 37 * All rights reserved. 38 * 39 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. All advertising materials mentioning features or use of this software 50 * must display the following acknowledgement: 51 * This product includes software developed for the NetBSD Project by 52 * Wasabi Systems, Inc. 53 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 54 * or promote products derived from this software without specific prior 55 * written permission. 56 * 57 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 58 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 59 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 60 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 61 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 62 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 63 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 64 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 65 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 66 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 67 * POSSIBILITY OF SUCH DAMAGE. 68 */ 69 70#include "assym.h" 71 72#include <machine/asm.h> 73#include <machine/cpu.h> 74#include <machine/frame.h> 75 76#include "opt_compat_netbsd.h" 77#include "opt_execfmt.h" 78#include "opt_multiprocessor.h" 79 80#include "opt_arm_intr_impl.h" 81#ifdef ARM_INTR_IMPL 82#include ARM_INTR_IMPL 83#else 84#error ARM_INTR_IMPL not defined 85#endif 86 87#ifndef ARM_IRQ_HANDLER 88#error ARM_IRQ_HANDLER not defined 89#endif 90 91#if defined(COMPAT_15) && defined(EXEC_AOUT) 92.Lcpufuncs: 93 .word _C_LABEL(cpufuncs) 94#ifndef MULTIPROCESSOR 95.Lcurpcb: 96 .word _C_LABEL(curpcb) 97.Lcpu_info_store: 98 .word _C_LABEL(cpu_info_store) 99#define GET_CURPCB \ 100 ldr r1, .Lcurpcb ;\ 101 ldr r1, [r1] 102#define GET_CPUINFO \ 103 ldr r0, .Lcpu_info_store 104#else 105.Lcpu_info: 106 .word _C_LABEL(cpu_info) 107#define GET_CURPCB \ 108 ldr r4, .Lcpu_info ;\ 109 bl _C_LABEL(cpu_number) ;\ 110 ldr r0, [r4, r0, lsl #2] ;\ 111 ldr r1, [r0, #CI_CURPCB] 112#define GET_CPUINFO /* nothing to do */ 113#endif 114#define ENABLE_ALIGNMENT_FAULTS \ 115 GET_CURPCB ;\ 116 cmp r1, #0x00 /* curpcb NULL? */ ;\ 117 ldrne r1, [r1, #PCB_FLAGS] /* Fetch curpcb->pcb_flags */ ;\ 118 tstne r1, #PCB_NOALIGNFLT ;\ 119 beq 1f /* Alignment faults already enabled */ ;\ 120 GET_CPUINFO ;\ 121 ldr r2, .Lcpufuncs ;\ 122 ldr r1, [r0, #CI_CTRL] /* Fetch control register */ ;\ 123 mov r0, #-1 ;\ 124 mov lr, pc ;\ 125 ldr pc, [r2, #CF_CONTROL] /* Enable alignment faults */ ;\ 1261: 127#endif /* COMPAT_15 && EXEC_AOUT */ 128 129/* 130 * irq_entry: 131 * Main entry point for the IRQ vector. This is a generic version 132 * which can be used by different platforms. 133 */ 134 .text 135 .align 0 136.Lastpending: 137 .word _C_LABEL(astpending) 138.Lcurrent_intr_depth: 139 .word _C_LABEL(current_intr_depth) 140 141ASENTRY_NP(irq_entry) 142 sub lr, lr, #0x00000004 /* Adjust the lr */ 143 144 PUSHFRAMEINSVC /* Push an interrupt frame */ 145 146#if defined(COMPAT_15) && defined(EXEC_AOUT) 147 and r0, r0, #(PSR_MODE) /* Test for USR32 mode (r0 = spsr_all)*/ 148 teq r0, #(PSR_USR32_MODE) 149 bne 99f /* Not USR mode so skip AFLT check */ 150 ENABLE_ALIGNMENT_FAULTS 15199: 152#endif 153 154 /* 155 * Increment the interrupt nesting depth and call the interrupt 156 * dispatch routine. We've pushed a frame, so we can safely use 157 * callee-saved regs here. We use the following registers, which 158 * we expect to presist: 159 * 160 * r5 address of `current_intr_depth' variable 161 * r6 old value of `current_intr_depth' 162 */ 163 ldr r5, .Lcurrent_intr_depth 164 mov r0, sp /* arg for dispatcher */ 165 ldr r6, [r5] 166 add r1, r6, #1 167 str r1, [r5] 168 169 bl ARM_IRQ_HANDLER 170 171 /* 172 * Restore the old interrupt depth value (which should be the 173 * same as decrementing it at this point). 174 */ 175 str r6, [r5] 176 177 /* 178 * If we're returning to user mode, check for pending ASTs. 179 */ 180 ldr r0, [sp] /* Get the SPSR from stack */ 181 and r0, r0, #(PSR_MODE) /* Test for USR32 mode before the IRQ */ 182 teq r0, #(PSR_USR32_MODE) 183 bne .Lirq_do_exit /* Nope, get out now */ 184 185 ldr r5, .Lastpending 186#if defined(COMPAT_15) && defined(EXEC_AOUT) && !defined(MULTIPROCESSOR) 187 ldr r6, .Lcurpcb 188 ldr r7, .Lcpu_info_store 189#endif 190 191.Lirq_ast_loop: 192 ldr r1, [r5] /* Do we have an AST pending? */ 193 teq r1, #0x00000000 194 bne .Lirq_do_ast /* Yup. Go deal with it */ 195 196#if defined(COMPAT_15) && defined(EXEC_AOUT) 197 /* Disable alignment faults for the process, if necessary. */ 198#ifdef MULTIPROCESSOR 199 ldr r7, .Lcpu_info 200 bl _C_LABEL(cpu_number) 201 ldr r7, [r7, r0, lsl #2] 202 ldr r1, [r7, #CI_CURPCB] 203#else 204 ldr r1, [r6] 205#endif 206 cmp r1, #0x00 /* curpcb NULL? */ 207 ldrne r1, [r1, #PCB_FLAGS] /* Fetch curpcb->pcb_flags */ 208 tstne r1, #PCB_NOALIGNFLT 209 beq 1f /* Keep alignment faults enabled */ 210 ldr r1, [r7, #CI_CTRL] /* Fetch control register */ 211 ldr r2, .Lcpufuncs 212 mov r0, #-1 213 bic r1, r1, #CPU_CONTROL_AFLT_ENABLE /* Disable alignment faults */ 214 mov lr, pc 215 ldr pc, [r2, #CF_CONTROL] /* Set the new control register value */ 2161: 217#endif 218 219.Lirq_do_exit: 220 PULLFRAMEFROMSVCANDEXIT 221 movs pc, lr /* Exit */ 222 223.Lirq_do_ast: 224 mov r1, #0x00000000 225 str r1, [r5] /* Clear astpending */ 226 227 mrs r4, cpsr /* save CPSR */ 228 bic r0, r4, #(I32_bit) /* Enable IRQs */ 229 msr cpsr_c, r0 230 231 mov r0, sp 232 bl _C_LABEL(ast) /* ast(frame) */ 233 234 msr cpsr_c, r4 /* Disable IRQs */ 235 b .Lirq_ast_loop /* Check for more ASTs */ 236 237 .bss 238 .align 0 239 240 .global _C_LABEL(astpending) 241_C_LABEL(astpending): 242 .word 0 243 244 .global _C_LABEL(current_intr_depth) 245_C_LABEL(current_intr_depth): 246 .word 0 247 248 /* 249 * XXX Provide intrnames/intrcnt for legacy code, but 250 * don't actually use them. 251 */ 252 253 .global _C_LABEL(intrnames), _C_LABEL(eintrnames) 254 .global _C_LABEL(intrcnt), _C_LABEL(eintrcnt) 255_C_LABEL(intrnames): 256_C_LABEL(eintrnames): 257 258 .global _C_LABEL(intrcnt), _C_LABEL(sintrcnt), _C_LABEL(eintrcnt) 259_C_LABEL(intrcnt): 260_C_LABEL(eintrcnt): 261