hdisr_gcc.S
2.28 KB
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
/*@}*/