hdisr.S 2.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
/*
 * File      : hdisr.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://openlab.rt-thread.com/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 */

/**
 * @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 isr_table
D
dzzxzz 已提交
63
.globl rt_thread_switch_interrupt_flag
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
.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		/* get irqno */
	addl $0x2c, %eax
	movl (%eax), %eax	/* each item takes up 4bytes in isr_table,equl to isr_table[irqno] */
	shll $0x2, %eax
	movl $isr_table, %ebx
	addl %eax,%ebx
	call *(%ebx)
	call rt_interrupt_leave

D
dzzxzz 已提交
85 86
	/* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */
	movl $rt_thread_switch_interrupt_flag, %eax
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
	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

/*@}*/