Indentation fix, cleanup.
[AROS.git] / arch / i386-pc / kernel / core_interrupts.s
blob66b1f1a051ede1be406e0beb647f8a176da849ea
1 #include <aros/i386/asm.h>
3 #include "segments.h"
5 #define BUILD_IRQ(nr) \
6 .align 16, 0x90; \
7 .globl TRAP##nr##_trap; \
8 .type TRAP##nr##_trap, @function; \
9 TRAP##nr##_trap: \
10 pushl $0; \
11 pushl $##nr; \
12 jmp core_Interrupt; \
13 .size TRAP##nr##_trap, .-TRAP##nr##_trap;
15 #define BUILD_IRQ_ERR(nr) \
16 .align 16, 0x90; \
17 .globl TRAP##nr##_trap; \
18 .type TRAP##nr##_trap, @function; \
19 TRAP##nr##_trap: \
20 pushl $##nr; \
21 jmp core_Interrupt; \
22 .size TRAP##nr##_trap, .-TRAP##nr##_trap;
24 BUILD_IRQ(0x00) // Divide-By-Zero Exception
25 BUILD_IRQ(0x01) // Debug Exception
26 BUILD_IRQ(0x02) // NMI Exception
27 BUILD_IRQ(0x03) // Breakpoint Exception
28 BUILD_IRQ(0x04) // Overflow Exception
29 BUILD_IRQ(0x05) // Bound-Range Exception
30 BUILD_IRQ(0x06) // Invalid-Opcode Exception
31 BUILD_IRQ(0x07) // Device-Not-Available Exception
32 BUILD_IRQ_ERR(0x08) // Double-Fault Exception
33 BUILD_IRQ(0x09) // Unused (used to be Coprocesor-Segment-Overrun)
34 BUILD_IRQ_ERR(0x0a) // Invalid-TSS Exception
35 BUILD_IRQ_ERR(0x0b) // Segment-Not-Present Exception
36 BUILD_IRQ_ERR(0x0c) // Stack Exception
37 BUILD_IRQ_ERR(0x0d) // General-Protection Exception
38 BUILD_IRQ_ERR(0x0e) // Page-Fault Exception
39 BUILD_IRQ(0x0f) // Reserved
40 BUILD_IRQ(0x10) // Floating-Point Exception
41 BUILD_IRQ_ERR(0x11) // Alignment-Check Exception
42 BUILD_IRQ(0x12) // Machine-Check Exception
43 BUILD_IRQ(0x13) // SIMD-Floating-Point Exception
44 BUILD_IRQ(0x14)
45 BUILD_IRQ(0x15)
46 BUILD_IRQ(0x16)
47 BUILD_IRQ(0x17)
48 BUILD_IRQ(0x18)
49 BUILD_IRQ(0x19)
50 BUILD_IRQ(0x1a)
51 BUILD_IRQ(0x1b)
52 BUILD_IRQ(0x1c)
53 BUILD_IRQ(0x1d)
54 BUILD_IRQ(0x1e)
55 BUILD_IRQ(0x1f)
56 BUILD_IRQ(0x20)
57 BUILD_IRQ(0x21)
58 BUILD_IRQ(0x22)
59 BUILD_IRQ(0x23)
60 BUILD_IRQ(0x24)
61 BUILD_IRQ(0x25)
62 BUILD_IRQ(0x26)
63 BUILD_IRQ(0x27)
64 BUILD_IRQ(0x28)
65 BUILD_IRQ(0x29)
66 BUILD_IRQ(0x2a)
67 BUILD_IRQ(0x2b)
68 BUILD_IRQ(0x2c)
69 BUILD_IRQ(0x2d)
70 BUILD_IRQ(0x2e)
71 BUILD_IRQ(0x2f)
73 BUILD_IRQ(0x80) // SysCall exception
74 BUILD_IRQ(0xFE) // APIC Error Exception
76 .align 16, 0x90
77 .globl core_Interrupt
78 .type core_Interrupt,@function
80 core_Interrupt: // At this point two ULONGs for segment registers are
81 // already reserved. They are occupied by error code and IRQ number
82 pushl $0 // Reserve two more ULONGs (for ES and DS)
83 pushl $0
84 pushl %ebp // Now save GPRs
85 pushl %edi
86 pushl %esi
87 pushl %edx
88 pushl %ecx
89 pushl %ebx
90 pushl %eax
91 pushl $ECF_SEGMENTS // Flags. We have no FPU context here and even no pointer for it.
92 movl %esp, %ebx // Fixate context pointer in EBX
93 movl reg_fs(%ebx), %eax // IRQ number - third argument to core_IRQHandle()
94 pushl %eax
95 movl reg_gs(%ebx), %eax // Error number - second argument
96 pushl %eax
97 pushl %ebx // Context pointer - first argument
98 xorl %eax, %eax // Zero-pad segments
99 mov %ds, %ax // Now save segment registers
100 movl %eax, reg_ds(%ebx)
101 mov %es, %ax
102 movl %eax, reg_es(%ebx)
103 mov %fs, %ax
104 movl %eax, reg_fs(%ebx)
105 mov %gs, %ax
106 movl %eax, reg_gs(%ebx)
107 mov $KERNEL_DS, %ax // We are supervisor now
108 mov %ax, %ds
109 mov %ax, %es
111 call handleException // Call C handler. EBX will be preserved.
112 restoreRegs:
113 movl Flags(%ebx), %eax // Test if the context contains segment registers
114 test $ECF_SEGMENTS, %eax
115 je noSegments
116 movl reg_ds(%ebx), %eax // Restore segment registers if present
117 mov %ax, %ds
118 movl reg_es(%ebx), %eax
119 mov %ax, %es
120 movl reg_fs(%ebx), %eax
121 mov %ax, %fs
122 movl reg_gs(%ebx), %eax
123 mov %ax, %gs
124 noSegments:
125 movl %ebx, %esp // Load context pointer into SP, we will pop everything
126 popl %eax // These were flags, just remove them
127 popl %eax // Restore GPRs
128 popl %ebx
129 popl %ecx
130 popl %edx
131 popl %esi
132 popl %edi
133 popl %ebp
134 addl $16, %esp // Remove segments
136 .globl core_Unused_Int
137 .type core_Unused_Int, @function
138 core_Unused_Int:
139 iret
140 .size core_Interrupt, .-core_Interrupt
142 .globl core_LeaveInterrupt
143 .type core_LeaveInterrupt, @function
144 core_LeaveInterrupt:
145 popl %ebx // Remove return address
146 popl %ebx // Get argument
147 jmp restoreRegs
148 .size core_LeaveInterrupt, .-core_LeaveInterrupt
150 .globl core_Supervisor
151 .type core_Supervisor, @function
153 core_Supervisor:
154 popl %ebx // Similar to above, but chains to the routine
155 popl %ebx // pointed to by EDI
156 movl Flags(%ebx), %eax // Note that data segments will be reset back to user-mode values
157 test $ECF_SEGMENTS, %eax
158 je sv_noSegments
159 movl reg_ds(%ebx), %eax
160 mov %ax, %ds
161 movl reg_es(%ebx), %eax
162 mov %ax, %es
163 movl reg_fs(%ebx), %eax
164 mov %ax, %fs
165 movl reg_gs(%ebx), %eax
166 mov %ax, %gs
167 sv_noSegments:
168 movl %ebx, %esp
169 popl %eax
170 popl %eax
171 popl %ebx
172 popl %ecx
173 popl %edx
174 popl %esi
175 popl %edi
176 popl %ebp
177 addl $16, %esp
178 jmp *%edi