get the kernel building again (definitely doesn't work)
[newos.git] / kernel / arch / x86_64 / arch_interrupts.S
blob0dbe56b954184b312c49a199b2d112657de2e3f9
1 /*
2 ** Copyright 2001-2004, Travis Geiselbrecht. All rights reserved.
3 ** Copyright 2002, Michael Noisternig. All rights reserved.
4 ** Distributed under the terms of the NewOS License.
5 */
7 #include <kernel/arch/x86_64/descriptors.h>
8 #include <kernel/arch/x86_64/kernel.h>
10 #define FUNCTION(x) .global x; .type x,@function; x
12 .text
14 #define TRAP_ERRC(name, vector) \
15 .globl name; \
16 .type x,@function; \
17 .align 8; \
18 name: \
19         push    $vector; \
20         jmp             int_bottom
22 #define TRAP(name, vector) \
23 .globl name; \
24 .type x,@function; \
25 .align 8; \
26 name: \
27         push    $0; \
28         push    $vector; \
29         jmp             int_bottom
31 TRAP(trap0, 0)
32 TRAP(trap1, 1)
33 TRAP(trap2, 2)
34 TRAP(trap3, 3)
35 TRAP(trap4, 4)
36 TRAP(trap5, 5)
37 TRAP(trap6, 6)
38 TRAP(trap7, 7)
39 TRAP_ERRC(trap8, 8)
40 TRAP(trap9, 9)
41 TRAP_ERRC(trap10, 10)
42 TRAP_ERRC(trap11, 11)
43 TRAP_ERRC(trap12, 12)
44 TRAP_ERRC(trap13, 13)
45 TRAP_ERRC(trap14, 14)
46 TRAP(trap16, 16)
47 TRAP_ERRC(trap17, 17)
48 TRAP(trap18, 18)
49 TRAP(trap19, 19)
51 TRAP(trap32, 32)
52 TRAP(trap33, 33)
53 TRAP(trap34, 34)
54 TRAP(trap35, 35)
55 TRAP(trap36, 36)
56 TRAP(trap37, 37)
57 TRAP(trap38, 38)
58 TRAP(trap39, 39)
59 TRAP(trap40, 40)
60 TRAP(trap41, 41)
61 TRAP(trap42, 42)
62 TRAP(trap43, 43)
63 TRAP(trap44, 44)
64 TRAP(trap45, 45)
65 TRAP(trap46, 46)
66 TRAP(trap47, 47)
68 TRAP(trap99, 99)
70 TRAP(trap251, 251)
71 TRAP(trap252, 252)
72 TRAP(trap253, 253)
73 TRAP(trap254, 254)
74 TRAP(trap255, 255)
76 .align 16
77 .globl int_bottom
78 int_bottom:
79         /* push all the GP regs except rsp */
80         push    %rax
81         push    %rcx
82         push    %rdx
83         push    %rbx
84         push    %rsp
85         push    %rbp
86         push    %rsi
87         push    %rdi
88         push    %r8
89         push    %r9
90         push    %r10
91         push    %r11
92         push    %r12
93         push    %r13
94         push    %r14
95         push    %r15
96         push    %fs
97         push    %gs
98         cld
100         call    x86_64_handle_trap
102         pop             %gs
103         pop             %fs
104         pop             %r15
105         pop             %r14
106         pop             %r13
107         pop             %r12
108         pop             %r11
109         pop             %r10
110         pop             %r9
111         pop             %r8
112         pop             %rdi
113         pop             %rsi
114         pop             %rbp
115         pop             %rsp
116         pop             %rbx
117         pop             %rdx
118         pop             %rcx
119         pop             %rax
121         add             $16,%rsp
122         iret
124 /* syscall entry point. arg passing is as follows:
125  * eax: vector number
126  * ecx: number of words on stack
127  * edx: pointer to args on user stack
129  * algorithm: push all registers, copy arguments to kernel stack, indirect
130  * jump through syscall_table (in kernel/syscalls.c).
131  */ 
132 .align 8
133 FUNCTION(x86_64_syscall_vector):
134 #warning implement x86_64_syscall_vector
135 #if 0
136         /* push a standard iframe to the stack */
137         pushl   $0              // error code 0
138         pushl   $99             // vector 99 (syscall)
139         pushl   %edx
140         pushl   %eax
141         pusha
142         push    %ds
143         push    %es
144         push    %fs
145         push    %gs
146         movl    $KERNEL_DATA_SEG,%ebx
147         cld
148         movl    %ebx,%ds
149         movl    %ebx,%es
151         /* save the current kernel stack, so we can restore to here in case of any error */
152         mov             %esp,%ebp
154 #if 0
155         /* print the syscall */
156         push    num_syscall_table_entries
157         push    %edx
158         push    %ecx
159         push    %eax
160         movl    %dr3,%ebx
161         addl    $12,%ebx
162         pushl   (%ebx)
163         push    $syscall_entry_msg
164         call    dprintf
165         add             $8,%esp
166         pop             %eax
167         pop             %ecx
168         pop             %edx
169         add             $4,%esp
170 #endif
172         /* sanity check vector number */
173         test    %eax,%eax
174         js              syscall_vector_error
175         cmp             num_syscall_table_entries,%eax
176         jge             syscall_vector_error
178         /* sanity check number of args (must be 0-15) */
179         test    $0xfffffff0,%ecx
180         jnz             syscall_vector_error
182         /* check to make sure the args pointer is not inside kernel space */
183         test    $KERNEL_ADDR_MASK,%edx
184         jnz             syscall_vector_error
186         /* if the syscall has no args, fast path over the arg copy code */
187         test    %ecx,%ecx
188         jz              skip_arg_copy
190         /* set the fault handler in case we get an error copying data from the user stack */
191         movl    %dr3,%ebx                                       // get the current thread structure
192         mov             fault_handler_offset,%esi       // get the offset into the thread structure that fault_handler is
193         lea             (%ebx,%esi),%ebx
194         mov             $syscall_vector_error,%esi
195         mov             %esi,(%ebx)                                     // stick the error handler into t->fault_handler
197         /* copy the appropriate number of args to the stack */
198         shl             $2,%ecx
199         sub             %ecx,%esp                               // move the stack pointer down by the amount we are about to dump on it
200         shr             $2,%ecx
202         mov             %edx,%esi                               // source is user space stack
203         mov             %esp,%edi                               // dest is kernel stack
204         rep 
205         movsl                                                   // copy them
207         movl    $0,(%ebx)                               // unset the error handler       
209 skip_arg_copy:
210         movl    %eax,%esi                               // move the vector number over to %esi
212         /* push the current iframe into the iframe stack */
213         pushl   %ebp
214         call    x86_64_push_frame
215         addl    $4,%esp
217         /* do kernel work upon entry */
218         call    thread_atkernel_entry
220         /* load the syscall vector table */
221         movl    $syscall_table,%ebx
222         call    *(%ebx,%esi,4)
224         /* save the return code into the iframe */
225         movl    %edx,0x24(%ebp)
226         movl    %eax,0x2c(%ebp)
228         /* do any cleanup work when leaving the kernel */
229         call    thread_atkernel_exit
231         call    x86_64_pop_iframe
233 syscall_vector_exit:
234         /* put the kernel stack back where it was before we pushed the args */
235         mov             %ebp,%esp
237         /* restore saved regs */
238         pop             %gs
239         pop             %fs
240         pop             %es
241         pop             %ds
243         /* reverse the pusha from above */
244         popa
245         addl    $16,%esp // no need to pop orig_eax,orig_edx,vector,error_code
246         iret
248 syscall_vector_error:
249         xorl    $0xffffffff,%edx
250         movl    %edx,0x24(%ebp)
251         movl    $-4,0x2c(%ebp)
252         jmp             syscall_vector_exit
254 syscall_entry_msg:
255         .ascii  "syscall tid 0x%x eax %d ecx %d edx 0x%x max syscall 0x%x\n\0"
256 bleh:
257         .ascii  "here 0x%x\n\0"
259         .align  4
260 #endif
262 #warning make sure this matches the syscall mechanism
263 FUNCTION(x86_64_return_from_signal):
264         add             $12, %rsp       // Flushes the 3 arguments to sa_handler
265         mov             $81, %rax       // This syscall will restore the cpu context to the
266         mov             $0, %rcx        // one existing before calling the signal handler
267         int             $99
268         ret
269 FUNCTION(x86_64_end_return_from_signal):