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
 | |
| 
 | |
| /*@}*/
 |