irq_dispatch.S revision 1.3
1/* $NetBSD: irq_dispatch.S,v 1.3 2003/10/25 20:42:49 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 ldr r1, [r1, #PCB_FLAGS] /* Fetch curpcb->pcb_flags */ ;\ 117 tst r1, #PCB_NOALIGNFLT ;\ 118 beq 1f /* Alignment faults already enabled */ ;\ 119 GET_CPUINFO ;\ 120 ldr r2, .Lcpufuncs ;\ 121 ldr r1, [r0, #CI_CTRL] /* Fetch control register */ ;\ 122 mov r0, #-1 ;\ 123 mov lr, pc ;\ 124 ldr pc, [r2, #CF_CONTROL] /* Enable alignment faults */ ;\ 1251: 126#endif /* COMPAT_15 && EXEC_AOUT */ 127 128/* 129 * irq_entry: 130 * Main entry point for the IRQ vector. This is a generic version 131 * which can be used by different platforms. 132 */ 133 .text 134 .align 0 135.Lastpending: 136 .word _C_LABEL(astpending) 137.Lcurrent_intr_depth: 138 .word _C_LABEL(current_intr_depth) 139 140ASENTRY_NP(irq_entry) 141 sub lr, lr, #0x00000004 /* Adjust the lr */ 142 143 PUSHFRAMEINSVC /* Push an interrupt frame */ 144 145#if defined(COMPAT_15) && defined(EXEC_AOUT) 146 and r0, r0, #(PSR_MODE) /* Test for USR32 mode (r0 = spsr_all)*/ 147 teq r0, #(PSR_USR32_MODE) 148 bne 99f /* Not USR mode so skip AFLT check */ 149 ENABLE_ALIGNMENT_FAULTS 15099: 151#endif 152 153 /* 154 * Increment the interrupt nesting depth and call the interrupt 155 * dispatch routine. We've pushed a frame, so we can safely use 156 * callee-saved regs here. We use the following registers, which 157 * we expect to presist: 158 * 159 * r5 address of `current_intr_depth' variable 160 * r6 old value of `current_intr_depth' 161 */ 162 ldr r5, .Lcurrent_intr_depth 163 mov r0, sp /* arg for dispatcher */ 164 ldr r6, [r5] 165 add r1, r6, #1 166 str r1, [r5] 167 168 bl ARM_IRQ_HANDLER 169 170 /* 171 * Restore the old interrupt depth value (which should be the 172 * same as decrementing it at this point). 173 */ 174 str r6, [r5] 175 176 /* 177 * If we're returning to user mode, check for pending ASTs. 178 */ 179 ldr r0, [sp] /* Get the SPSR from stack */ 180 and r0, r0, #(PSR_MODE) /* Test for USR32 mode before the IRQ */ 181 teq r0, #(PSR_USR32_MODE) 182 bne .Lirq_do_exit /* Nope, get out now */ 183 184 ldr r5, .Lastpending 185#if defined(COMPAT_15) && defined(EXEC_AOUT) && !defined(MULTIPROCESSOR) 186 ldr r6, .Lcurpcb 187 ldr r7, .Lcpu_info_store 188#endif 189 190.Lirq_ast_loop: 191 ldr r1, [r5] /* Do we have an AST pending? */ 192 teq r1, #0x00000000 193 bne .Lirq_do_ast /* Yup. Go deal with it */ 194 195#if defined(COMPAT_15) && defined(EXEC_AOUT) 196 /* Disable alignment faults for the process, if necessary. */ 197#ifdef MULTIPROCESSOR 198 ldr r7, .Lcpu_info 199 bl _C_LABEL(cpu_number) 200 ldr r7, [r7, r0, lsl #2] 201 ldr r1, [r7, #CI_CURPCB] 202#else 203 ldr r1, [r6] 204#endif 205 ldr r1, [r1, #PCB_FLAGS] /* Fetch curpcb->pcb_flags */ 206 tst r1, #PCB_NOALIGNFLT 207 beq 1f /* Keep alignment faults enabled */ 208 ldr r1, [r7, #CI_CTRL] /* Fetch control register */ 209 ldr r2, .Lcpufuncs 210 mov r0, #-1 211 bic r1, r1, #CPU_CONTROL_AFLT_ENABLE /* Disable alignment faults */ 212 mov lr, pc 213 ldr pc, [r2, #CF_CONTROL] /* Set the new control register value */ 2141: 215#endif 216 217.Lirq_do_exit: 218 PULLFRAMEFROMSVCANDEXIT 219 movs pc, lr /* Exit */ 220 221.Lirq_do_ast: 222 mov r1, #0x00000000 223 str r1, [r5] /* Clear astpending */ 224 225 mrs r4, cpsr /* save CPSR */ 226 bic r0, r4, #(I32_bit) /* Enable IRQs */ 227 msr cpsr_c, r0 228 229 mov r0, sp 230 bl _C_LABEL(ast) /* ast(frame) */ 231 232 msr cpsr_c, r4 /* Disable IRQs */ 233 b .Lirq_ast_loop /* Check for more ASTs */ 234 235 .bss 236 .align 0 237 238 .global _C_LABEL(astpending) 239_C_LABEL(astpending): 240 .word 0 241 242 .global _C_LABEL(current_intr_depth) 243_C_LABEL(current_intr_depth): 244 .word 0 245 246 /* 247 * XXX Provide intrnames/intrcnt for legacy code, but 248 * don't actually use them. 249 */ 250 251 .global _C_LABEL(intrnames), _C_LABEL(eintrnames) 252 .global _C_LABEL(intrcnt), _C_LABEL(eintrcnt) 253_C_LABEL(intrnames): 254_C_LABEL(eintrnames): 255 256 .global _C_LABEL(intrcnt), _C_LABEL(sintrcnt), _C_LABEL(eintrcnt) 257_C_LABEL(intrcnt): 258_C_LABEL(eintrcnt): 259