193 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
			
		
		
	
	
			193 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
# 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;
 |