/* $NetBSD: irq_dispatch.S,v 1.4 2003/10/26 11:34:29 scw Exp $ */ /* * Copyright (c) 2002 Fujitsu Component Limited * Copyright (c) 2002 Genetec Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of The Fujitsu Component Limited nor the name of * Genetec corporation may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC * CORPORATION ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL FUJITSU COMPONENT LIMITED OR GENETEC * CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Copyright (c) 2002, 2003 Wasabi Systems, Inc. * All rights reserved. * * Written by Jason R. Thorpe for Wasabi Systems, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for the NetBSD Project by * Wasabi Systems, Inc. * 4. The name of Wasabi Systems, Inc. may not be used to endorse * or promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "assym.h" #include #include #include #include "opt_compat_netbsd.h" #include "opt_execfmt.h" #include "opt_multiprocessor.h" #include "opt_arm_intr_impl.h" #ifdef ARM_INTR_IMPL #include ARM_INTR_IMPL #else #error ARM_INTR_IMPL not defined #endif #ifndef ARM_IRQ_HANDLER #error ARM_IRQ_HANDLER not defined #endif #if defined(COMPAT_15) && defined(EXEC_AOUT) .Lcpufuncs: .word _C_LABEL(cpufuncs) #ifndef MULTIPROCESSOR .Lcurpcb: .word _C_LABEL(curpcb) .Lcpu_info_store: .word _C_LABEL(cpu_info_store) #define GET_CURPCB \ ldr r1, .Lcurpcb ;\ ldr r1, [r1] #define GET_CPUINFO \ ldr r0, .Lcpu_info_store #else .Lcpu_info: .word _C_LABEL(cpu_info) #define GET_CURPCB \ ldr r4, .Lcpu_info ;\ bl _C_LABEL(cpu_number) ;\ ldr r0, [r4, r0, lsl #2] ;\ ldr r1, [r0, #CI_CURPCB] #define GET_CPUINFO /* nothing to do */ #endif #define ENABLE_ALIGNMENT_FAULTS \ GET_CURPCB ;\ cmp r1, #0x00 /* curpcb NULL? */ ;\ ldrne r1, [r1, #PCB_FLAGS] /* Fetch curpcb->pcb_flags */ ;\ tstne r1, #PCB_NOALIGNFLT ;\ beq 1f /* Alignment faults already enabled */ ;\ GET_CPUINFO ;\ ldr r2, .Lcpufuncs ;\ ldr r1, [r0, #CI_CTRL] /* Fetch control register */ ;\ mov r0, #-1 ;\ mov lr, pc ;\ ldr pc, [r2, #CF_CONTROL] /* Enable alignment faults */ ;\ 1: #endif /* COMPAT_15 && EXEC_AOUT */ /* * irq_entry: * Main entry point for the IRQ vector. This is a generic version * which can be used by different platforms. */ .text .align 0 .Lastpending: .word _C_LABEL(astpending) .Lcurrent_intr_depth: .word _C_LABEL(current_intr_depth) ASENTRY_NP(irq_entry) sub lr, lr, #0x00000004 /* Adjust the lr */ PUSHFRAMEINSVC /* Push an interrupt frame */ #if defined(COMPAT_15) && defined(EXEC_AOUT) and r0, r0, #(PSR_MODE) /* Test for USR32 mode (r0 = spsr_all)*/ teq r0, #(PSR_USR32_MODE) bne 99f /* Not USR mode so skip AFLT check */ ENABLE_ALIGNMENT_FAULTS 99: #endif /* * Increment the interrupt nesting depth and call the interrupt * dispatch routine. We've pushed a frame, so we can safely use * callee-saved regs here. We use the following registers, which * we expect to presist: * * r5 address of `current_intr_depth' variable * r6 old value of `current_intr_depth' */ ldr r5, .Lcurrent_intr_depth mov r0, sp /* arg for dispatcher */ ldr r6, [r5] add r1, r6, #1 str r1, [r5] bl ARM_IRQ_HANDLER /* * Restore the old interrupt depth value (which should be the * same as decrementing it at this point). */ str r6, [r5] /* * If we're returning to user mode, check for pending ASTs. */ ldr r0, [sp] /* Get the SPSR from stack */ and r0, r0, #(PSR_MODE) /* Test for USR32 mode before the IRQ */ teq r0, #(PSR_USR32_MODE) bne .Lirq_do_exit /* Nope, get out now */ ldr r5, .Lastpending #if defined(COMPAT_15) && defined(EXEC_AOUT) && !defined(MULTIPROCESSOR) ldr r6, .Lcurpcb ldr r7, .Lcpu_info_store #endif .Lirq_ast_loop: ldr r1, [r5] /* Do we have an AST pending? */ teq r1, #0x00000000 bne .Lirq_do_ast /* Yup. Go deal with it */ #if defined(COMPAT_15) && defined(EXEC_AOUT) /* Disable alignment faults for the process, if necessary. */ #ifdef MULTIPROCESSOR ldr r7, .Lcpu_info bl _C_LABEL(cpu_number) ldr r7, [r7, r0, lsl #2] ldr r1, [r7, #CI_CURPCB] #else ldr r1, [r6] #endif cmp r1, #0x00 /* curpcb NULL? */ ldrne r1, [r1, #PCB_FLAGS] /* Fetch curpcb->pcb_flags */ tstne r1, #PCB_NOALIGNFLT beq 1f /* Keep alignment faults enabled */ ldr r1, [r7, #CI_CTRL] /* Fetch control register */ ldr r2, .Lcpufuncs mov r0, #-1 bic r1, r1, #CPU_CONTROL_AFLT_ENABLE /* Disable alignment faults */ mov lr, pc ldr pc, [r2, #CF_CONTROL] /* Set the new control register value */ 1: #endif .Lirq_do_exit: PULLFRAMEFROMSVCANDEXIT movs pc, lr /* Exit */ .Lirq_do_ast: mov r1, #0x00000000 str r1, [r5] /* Clear astpending */ mrs r4, cpsr /* save CPSR */ bic r0, r4, #(I32_bit) /* Enable IRQs */ msr cpsr_c, r0 mov r0, sp bl _C_LABEL(ast) /* ast(frame) */ msr cpsr_c, r4 /* Disable IRQs */ b .Lirq_ast_loop /* Check for more ASTs */ .bss .align 0 .global _C_LABEL(astpending) _C_LABEL(astpending): .word 0 .global _C_LABEL(current_intr_depth) _C_LABEL(current_intr_depth): .word 0 /* * XXX Provide intrnames/intrcnt for legacy code, but * don't actually use them. */ .global _C_LABEL(intrnames), _C_LABEL(eintrnames) .global _C_LABEL(intrcnt), _C_LABEL(eintrcnt) _C_LABEL(intrnames): _C_LABEL(eintrnames): .global _C_LABEL(intrcnt), _C_LABEL(sintrcnt), _C_LABEL(eintrcnt) _C_LABEL(intrcnt): _C_LABEL(eintrcnt):