1 #include <aros/i386/asm.h>
5 #define BUILD_IRQ(nr) \
7 .globl IRQ##nr##_intr; \
8 .type IRQ##nr##_intr, @function; \
12 jmp core_EnterInterrupt; \
13 .size IRQ##nr##_intr, .-IRQ##nr##_intr;
15 #define BUILD_IRQ_ERR(nr) \
17 .globl IRQ##nr##_intr; \
18 .type IRQ##nr##_intr, @function; \
21 jmp core_EnterInterrupt; \
22 .size IRQ##nr##_intr, .-IRQ##nr##_intr;
24 #define B(x,y) BUILD_IRQ(x##y)
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
63 BUILD_16
(0x2) // Hardware IRQs.
..
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
)
101 pushl
%ebp
// Now save GPRs
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
()
112 movl reg_gs
(%ebx
), %eax
// Error number
- second argument
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
)
119 movl
%eax
, reg_es
(%ebx
)
121 movl
%eax
, reg_fs
(%ebx
)
123 movl
%eax
, reg_gs
(%ebx
)
124 mov $KERNEL_DS
, %ax
// We are supervisor now
128 call core_IRQHandle
// Call C handler. EBX will
be preserved.
130 movl Flags
(%ebx
), %eax
// Test if the context contains segment registers
131 test $ECF_SEGMENTS
, %eax
133 movl reg_ds
(%ebx
), %eax
// Restore segment registers if present
135 movl reg_es
(%ebx
), %eax
137 movl reg_fs
(%ebx
), %eax
139 movl reg_gs
(%ebx
), %eax
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
151 addl $
16, %esp
// Remove segments
153 .globl core_DefaultIRET
154 .type core_DefaultIRET, @function
157 .size core_EnterInterrupt, .-core_EnterInterrupt
159 .globl core_LeaveInterrupt
160 .type core_LeaveInterrupt, @function
162 popl
%ebx
// Remove return address
163 popl
%ebx
// Get argument
165 .size core_LeaveInterrupt, .-core_LeaveInterrupt
167 .globl core_Supervisor
168 .type core_Supervisor, @function
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
176 movl reg_ds
(%ebx
), %eax
178 movl reg_es
(%ebx
), %eax
180 movl reg_fs
(%ebx
), %eax
182 movl reg_gs
(%ebx
), %eax