revert between 56095 -> 55830 in arch
[AROS.git] / arch / i386-pc / kernel / core_interrupts.s
blob4833907a4a18d7dfd86a61b1db14c4100df1d5a3
1 #include <aros/i386/asm.h>
3 #include "segments.h"
5 #define BUILD_IRQ(nr) \
6 .align 16, 0x90; \
7 .globl IRQ##nr##_intr; \
8 .type IRQ##nr##_intr, @function; \
9 IRQ##nr##_intr: \
10 pushl $0; \
11 pushl $##nr; \
12 jmp core_EnterInterrupt; \
13 .size IRQ##nr##_intr, .-IRQ##nr##_intr;
15 #define BUILD_IRQ_ERR(nr) \
16 .align 16, 0x90; \
17 .globl IRQ##nr##_intr; \
18 .type IRQ##nr##_intr, @function; \
19 IRQ##nr##_intr: \
20 pushl $##nr; \
21 jmp core_EnterInterrupt; \
22 .size IRQ##nr##_intr, .-IRQ##nr##_intr;
24 #define B(x,y) BUILD_IRQ(x##y)
25 #define BUILD_16(x) \
26 B(x,0) B(x,1) B(x,2) B(x,3) B(x,4) B(x,5) B(x,6) B(x,7) \
27 B(x,8) B(x,9) B(x,A) B(x,B) B(x,C) B(x,D) B(x,E) B(x,F)
29 BUILD_IRQ(0x00) // Divide-By-Zero Exception
30 BUILD_IRQ(0x01) // Debug Exception
31 BUILD_IRQ(0x02) // NMI Exception
32 BUILD_IRQ(0x03) // Breakpoint Exception
33 BUILD_IRQ(0x04) // Overflow Exception
34 BUILD_IRQ(0x05) // Bound-Range Exception
35 BUILD_IRQ(0x06) // Invalid-Opcode Exception
36 BUILD_IRQ(0x07) // Device-Not-Available Exception
37 BUILD_IRQ_ERR(0x08) // Double-Fault Exception
38 BUILD_IRQ(0x09) // Unused (used to be Coprocesor-Segment-Overrun)
39 BUILD_IRQ_ERR(0x0A) // Invalid-TSS Exception
40 BUILD_IRQ_ERR(0x0B) // Segment-Not-Present Exception
41 BUILD_IRQ_ERR(0x0C) // Stack Exception
42 BUILD_IRQ_ERR(0x0D) // General-Protection Exception
43 BUILD_IRQ_ERR(0x0E) // Page-Fault Exception
44 BUILD_IRQ(0x0F) // Reserved
45 BUILD_IRQ(0x10) // Floating-Point Exception
46 BUILD_IRQ_ERR(0x11) // Alignment-Check Exception
47 BUILD_IRQ(0x12) // Machine-Check Exception
48 BUILD_IRQ(0x13) // SIMD-Floating-Point Exception
49 BUILD_IRQ(0x14)
50 BUILD_IRQ(0x15)
51 BUILD_IRQ(0x16)
52 BUILD_IRQ(0x17)
53 BUILD_IRQ(0x18)
54 BUILD_IRQ(0x19)
55 BUILD_IRQ(0x1A)
56 BUILD_IRQ(0x1B)
57 BUILD_IRQ(0x1C)
58 BUILD_IRQ(0x1D)
59 BUILD_IRQ(0x1E)
60 BUILD_IRQ(0x1F)
63 BUILD_16(0x2) // Hardware IRQs...
64 BUILD_16(0x3)
65 BUILD_16(0x4)
66 BUILD_16(0x5)
67 BUILD_16(0x6)
68 BUILD_16(0x7)
69 BUILD_16(0x8)
70 BUILD_16(0x9)
71 BUILD_16(0xA)
72 BUILD_16(0xB)
73 BUILD_16(0xC)
74 BUILD_16(0xD)
75 BUILD_16(0xE)
76 BUILD_IRQ(0xF0)
77 BUILD_IRQ(0xF1)
78 BUILD_IRQ(0xF2)
79 BUILD_IRQ(0xF3)
80 BUILD_IRQ(0xF4)
81 BUILD_IRQ(0xF5)
82 BUILD_IRQ(0xF6)
83 BUILD_IRQ(0xF7)
84 BUILD_IRQ(0xF8)
85 BUILD_IRQ(0xF9)
86 BUILD_IRQ(0xFA)
87 BUILD_IRQ(0xFB)
88 BUILD_IRQ(0xFC)
89 BUILD_IRQ(0xFD)
90 BUILD_IRQ(0xFE)
91 BUILD_IRQ(0xFF)
93 .align 16, 0x90
94 .globl core_EnterInterrupt
95 .type core_EnterInterrupt,@function
97 core_EnterInterrupt: // At this point two ULONGs for segment registers are
98 // already reserved. They are occupied by error code and IRQ number
99 pushl $0 // Reserve two more ULONGs (for ES and DS)
100 pushl $0
101 pushl %ebp // Now save GPRs
102 pushl %edi
103 pushl %esi
104 pushl %edx
105 pushl %ecx
106 pushl %ebx
107 pushl %eax
108 pushl $ECF_SEGMENTS // Flags. We have no FPU context here and even no pointer for it.
109 movl %esp, %ebx // Fixate context pointer in EBX
110 movl reg_fs(%ebx), %eax // IRQ number - third argument to core_IRQHandle()
111 pushl %eax
112 movl reg_gs(%ebx), %eax // Error number - second argument
113 pushl %eax
114 pushl %ebx // Context pointer - first argument
115 xorl %eax, %eax // Zero-pad segments
116 mov %ds, %ax // Now save segment registers
117 movl %eax, reg_ds(%ebx)
118 mov %es, %ax
119 movl %eax, reg_es(%ebx)
120 mov %fs, %ax
121 movl %eax, reg_fs(%ebx)
122 mov %gs, %ax
123 movl %eax, reg_gs(%ebx)
124 mov $KERNEL_DS, %ax // We are supervisor now
125 mov %ax, %ds
126 mov %ax, %es
128 call core_IRQHandle // Call C handler. EBX will be preserved.
129 restoreRegs:
130 movl Flags(%ebx), %eax // Test if the context contains segment registers
131 test $ECF_SEGMENTS, %eax
132 je noSegments
133 movl reg_ds(%ebx), %eax // Restore segment registers if present
134 mov %ax, %ds
135 movl reg_es(%ebx), %eax
136 mov %ax, %es
137 movl reg_fs(%ebx), %eax
138 mov %ax, %fs
139 movl reg_gs(%ebx), %eax
140 mov %ax, %gs
141 noSegments:
142 movl %ebx, %esp // Load context pointer into SP, we will pop everything
143 popl %eax // These were flags, just remove them
144 popl %eax // Restore GPRs
145 popl %ebx
146 popl %ecx
147 popl %edx
148 popl %esi
149 popl %edi
150 popl %ebp
151 addl $16, %esp // Remove segments
153 .globl core_DefaultIRET
154 .type core_DefaultIRET, @function
155 core_DefaultIRET:
156 iret
157 .size core_EnterInterrupt, .-core_EnterInterrupt
159 .globl core_LeaveInterrupt
160 .type core_LeaveInterrupt, @function
161 core_LeaveInterrupt:
162 popl %ebx // Remove return address
163 popl %ebx // Get argument
164 jmp restoreRegs
165 .size core_LeaveInterrupt, .-core_LeaveInterrupt
167 .globl core_Supervisor
168 .type core_Supervisor, @function
170 core_Supervisor:
171 popl %ebx // Similar to above, but chains to the routine
172 popl %ebx // pointed to by EDI
173 movl Flags(%ebx), %eax // Note that data segments will be reset back to user-mode values
174 test $ECF_SEGMENTS, %eax
175 je sv_noSegments
176 movl reg_ds(%ebx), %eax
177 mov %ax, %ds
178 movl reg_es(%ebx), %eax
179 mov %ax, %es
180 movl reg_fs(%ebx), %eax
181 mov %ax, %fs
182 movl reg_gs(%ebx), %eax
183 mov %ax, %gs
184 sv_noSegments:
185 movl %ebx, %esp
186 popl %eax
187 popl %eax
188 popl %ebx
189 popl %ecx
190 popl %edx
191 popl %esi
192 popl %edi
193 popl %ebp
194 addl $16, %esp
195 jmp *%edi