diff options
Diffstat (limited to 'libgloss/epiphany/epiphany-ivthandlers.S')
-rw-r--r-- | libgloss/epiphany/epiphany-ivthandlers.S | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/libgloss/epiphany/epiphany-ivthandlers.S b/libgloss/epiphany/epiphany-ivthandlers.S new file mode 100644 index 000000000..0731a6b06 --- /dev/null +++ b/libgloss/epiphany/epiphany-ivthandlers.S @@ -0,0 +1,192 @@ +# EPIPHANY implementation of wrappers over user C ISR () + +# Copyright (c) 2011, Adapteva, Inc. +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Adapteva nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. + +.section RESERVED_CRT0,"a",@progbits ; +.set sw_exception_v_n, 1 +.set page_miss_v_n, 2 +.set timer0_expired_v_n, 3; +.set timer1_expired_v_n, 4; +.set message_v_n, 5; +.set dma0_v_n, 6; +.set dma1_v_n, 7; +.set wand_v_n, 8; +.set soft_v_n, 9 + +// preserve isr-mods to ACTIVE, GID, KERNEL, WAND, & EXCAUSE bits in the status reg +.set status_mask, 0x0007000f; +// for the wand isr, preserve isr-mods to ACTIVE, GID, KERNEL, & EXCAUSE, but +// clear the WAND bit. +.set wand_status_mask, 0x00070007; + +//IVT wrappers + +.global _DEFAULT_ISR_CALLBACK; +.balign 4 +.type _DEFAULT_ISR_CALLBACK, %function +_DEFAULT_ISR_CALLBACK: + rts +.size _DEFAULT_ISR_CALLBACK, .-_DEFAULT_ISR_CALLBACK + + +.global _DEFAULT_ISR_CALLBACK_FOR_sw_exception_v; +.balign 4 +.type _DEFAULT_ISR_CALLBACK_FOR_sw_exception_v, %function +_DEFAULT_ISR_CALLBACK_FOR_sw_exception_v: + trap 5;; FAIL +.size _DEFAULT_ISR_CALLBACK_FOR_sw_exception_v, .-_DEFAULT_ISR_CALLBACK_FOR_sw_exception_v + + +.set NUMBER_ENTRIES_IN_IVT, 8 +.global _ISR_VECTOR; +.balign 4 +.type _ISR_VECTOR, %object +_ISR_VECTOR: + .word _DEFAULT_ISR_CALLBACK_FOR_sw_exception_v; reset + .word _DEFAULT_ISR_CALLBACK_FOR_sw_exception_v; sw_exception + .word _DEFAULT_ISR_CALLBACK_FOR_sw_exception_v; page_miss + .rept NUMBER_ENTRIES_IN_IVT + .word _DEFAULT_ISR_CALLBACK + .endr +.size _ISR_VECTOR, .-_ISR_VECTOR + +.macro IVT_ENTRY_CALL entry_v_ + ;; assuming we have valid frame poiter + + str fp, [sp],-0x10 + str r0, [sp,+0xf] + str r1, [sp,+0xe] + mov r0, \entry_v_ +.if \entry_v_ == wand_v_n + mov r1, %low(wand_status_mask) ; this mask will exclude WAND, so it will + movt r1, %high(wand_status_mask) ; be forcibly cleared +.else + mov r1, %low(status_mask) + movt r1, %high(status_mask) +.endif + str r1, [sp,0x9] ; save the status register isr-preserve mask on the stack + b __dispatcher +.endm + +.global __dispatcher; +.balign 4 +.type __dispatcher, %function +__dispatcher: + str lr, [sp,+0xd] + movfs.l r1,status + str r1, [sp,+0xc] + movfs.l r1,iret + str r1, [sp,+0xb] + str r2, [sp,+0xa] + str r3, [sp,+0x8] + + mov fp,sp + + //TODO allow nesting + //gie + + lsl r2, r0, 2 + mov r1, %low(_ISR_VECTOR) + add r2, r2, r1 + ldr r1, [r2,0] ;; r1 = _ISR_VECTOR[entry_v] + mov r2, 3 + add r0, r0, r2 ;; r0 = signum + jalr r1 + + mov sp,fp + + //gid + + // preserve isr-modifications to some of the bits in the status register, + // but restore the rest to pre-interrupt values. + // status = (status[post_isr] & status_mask) | (status[pre_isr] & ~status_mask) + + ldr.l r2, [sp, 9] ; fetch the status register isr preserve mask from the stack + movfs r1, status + and r1, r1, r2; (status[post_isr] & status_mask) + + ldr r0, [sp,+0xc] + mov r2, %low(~status_mask) + movt r2, %high(~status_mask) + and r0, r0, r2; (status[pre_isr] & ~status_mask) + + orr r0, r0, r1 ; combine pre_isr & post_isr status bits + movts.l status, r0 + + ldr r0, [sp,+0xb] + movts.l iret,r0 + + ldr lr,[sp,+0xd]; + ldr r1,[sp,+0xe] + ldr r0,[sp,+0xf] + ldr r2,[sp,+0xa] + ldr r3,[sp,+0x8] + ldr fp,[sp],+0x10 + ldr fp,[sp,0] + rti +.size __dispatcher, .-__dispatcher + + +.global .sw_exception_v; +.type .sw_exception_v, %function +.sw_exception_v: + IVT_ENTRY_CALL sw_exception_v_n; +.size .sw_exception_v, .-.sw_exception_v + +.global .page_miss_v; +.type .page_miss_v, %function +.page_miss_v: + IVT_ENTRY_CALL page_miss_v_n; +.size .page_miss_v, .-.page_miss_v + +.global .timer0_expired_v; +.timer0_expired_v: + IVT_ENTRY_CALL timer0_expired_v_n; + +.global .timer1_expired_v; +.timer1_expired_v: + IVT_ENTRY_CALL timer1_expired_v_n; + +.global .message_v; +.message_v: + IVT_ENTRY_CALL message_v_n; + +.global .dma0_v; +.dma0_v: + IVT_ENTRY_CALL dma0_v_n; + +.global .dma1_v; +.dma1_v: + IVT_ENTRY_CALL dma1_v_n; + +.global .wand_v; +.wand_v: + IVT_ENTRY_CALL wand_v_n; + +.global .soft_v; +.soft_v: + IVT_ENTRY_CALL soft_v_n; |