123 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
		
		
			
		
	
	
			123 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
|  | /* | ||
|  |  * File      : hdisr_gcc.S | ||
|  |  * This file is part of RT-Thread RTOS | ||
|  |  * COPYRIGHT (C) 2006, RT-Thread Development Team | ||
|  |  * | ||
|  |  * The license and distribution terms for this file may be | ||
|  |  * found in the file LICENSE in this distribution or at | ||
|  |  * http://www.rt-thread.org/license/LICENSE | ||
|  |  * | ||
|  |  * Change Logs: | ||
|  |  * Date           Author       Notes | ||
|  |  * 2006-09-15     QiuYi        The first version | ||
|  |  */ | ||
|  | 
 | ||
|  | /** | ||
|  |  * @addtogroup I386
 | ||
|  |  */ | ||
|  | /*@{*/ | ||
|  | 
 | ||
|  | #define ENTRY(proc)\ | ||
|  | 	.align 2;\
 | ||
|  | 	.globl proc;\
 | ||
|  | 	.type proc,@function;\
 | ||
|  | 	proc: | ||
|  | #define HDINTERRUPTFNC(name,num) \ | ||
|  | 	ENTRY(name)\ | ||
|  | 	pushl $(num);\
 | ||
|  | 	jmp _hdinterrupts;\
 | ||
|  | 	.data;\
 | ||
|  | 	.long name;\
 | ||
|  | 	.text | ||
|  | 
 | ||
|  | .globl hdinterrupt_func
 | ||
|  | 	.data | ||
|  | 	.align 4
 | ||
|  | 	.type hdinterrupt_func,@object
 | ||
|  | 	hdinterrupt_func : | ||
|  | .text | ||
|  | 
 | ||
|  | /* the external device interrupts */ | ||
|  | HDINTERRUPTFNC(irq0, 0) | ||
|  | HDINTERRUPTFNC(irq1, 1) | ||
|  | HDINTERRUPTFNC(irq2, 2) | ||
|  | HDINTERRUPTFNC(irq3, 3) | ||
|  | HDINTERRUPTFNC(irq4, 4) | ||
|  | HDINTERRUPTFNC(irq5, 5) | ||
|  | HDINTERRUPTFNC(irq6, 6) | ||
|  | HDINTERRUPTFNC(irq7, 7) | ||
|  | HDINTERRUPTFNC(irq8, 8) | ||
|  | HDINTERRUPTFNC(irq9, 9) | ||
|  | HDINTERRUPTFNC(irq10, 10) | ||
|  | HDINTERRUPTFNC(irq11, 11) | ||
|  | HDINTERRUPTFNC(irq12, 12) | ||
|  | HDINTERRUPTFNC(irq13, 13) | ||
|  | HDINTERRUPTFNC(irq14, 14) | ||
|  | HDINTERRUPTFNC(irq15, 15) | ||
|  | 
 | ||
|  | .p2align 4,0x90 | ||
|  | .globl _hdinterrupts
 | ||
|  | .type _hdinterrupts,@function
 | ||
|  | .globl rt_interrupt_enter
 | ||
|  | .globl rt_interrupt_leave
 | ||
|  | .globl rt_hw_isr
 | ||
|  | .globl rt_thread_switch_interrupt_flag
 | ||
|  | .globl rt_interrupt_from_thread
 | ||
|  | .globl rt_interrupt_to_thread
 | ||
|  | 
 | ||
|  | _hdinterrupts: | ||
|  | 	push %ds | ||
|  | 	push %es | ||
|  | 	pushal | ||
|  | 	movw $0x10, %ax | ||
|  | 	movw %ax, %ds | ||
|  | 	movw %ax, %es | ||
|  | 	pushl %esp | ||
|  | 
 | ||
|  | 	call rt_interrupt_enter | ||
|  | 
 | ||
|  | 	movl %esp, %eax	      /* copy esp to eax */ | ||
|  | 	addl $0x2c, %eax      /* move to vector address */ | ||
|  | 	movl (%eax), %eax     /* vector(eax) = *eax */ | ||
|  | 
 | ||
|  | 	pushl %eax            /* push argument : int vector */ | ||
|  | 	call rt_hw_isr | ||
|  | 	add $4, %esp          /* restore argument */ | ||
|  | 
 | ||
|  | 	call rt_interrupt_leave | ||
|  | 
 | ||
|  | 	/* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */ | ||
|  | 	movl $rt_thread_switch_interrupt_flag, %eax | ||
|  | 	movl (%eax), %ebx | ||
|  | 	cmp $0x1, %ebx | ||
|  | 	jz _interrupt_thread_switch | ||
|  | 
 | ||
|  | 	popl %esp | ||
|  | 	popal | ||
|  | 	pop %es | ||
|  | 	pop %ds | ||
|  | 	add $4,%esp | ||
|  | 	iret | ||
|  | 
 | ||
|  | _interrupt_thread_switch: | ||
|  | 	popl %esp | ||
|  | 
 | ||
|  | 	movl $0x0, %ebx | ||
|  | 	movl %ebx, (%eax) | ||
|  | 
 | ||
|  | 	movl $rt_interrupt_from_thread, %eax | ||
|  | 	movl (%eax), %ebx | ||
|  | 	movl %esp, (%ebx) | ||
|  | 
 | ||
|  | 	movl $rt_interrupt_to_thread, %ecx | ||
|  | 	movl (%ecx), %edx | ||
|  | 	movl (%edx), %esp | ||
|  | 
 | ||
|  | 	popal | ||
|  | 	pop %es | ||
|  | 	pop %ds | ||
|  | 	add $4,%esp | ||
|  | 	iret | ||
|  | 
 | ||
|  | /*@}*/ |