Killing of parallel processes
[akaros.git] / kern / arch / i386 / trapentry.S
1 /* See COPYRIGHT for copyright information.
2  * The two TRAP* macros (minus the .data parts) are from the JOS project.
3  * Everything else:
4  * Copyright (c) 2009 The Regents of the University of California
5  * Barret Rhoden <brho@cs.berkeley.edu>
6  * See LICENSE for details.
7  */
8 #include <arch/mmu.h>
9 #include <arch/trap.h>
10 #include <ros/memlayout.h>
11
12 ###################################################################
13 # exceptions/interrupts
14 ###################################################################
15
16 /* The TRAPHANDLER macro defines a globally-visible function for handling
17  * a trap.  It pushes a trap number onto the stack, then jumps to _alltraps.
18  * It also builds this traps portion of the trap_tbl.
19  * Use TRAPHANDLER for traps where the CPU automatically pushes an error code.
20  */ 
21 #define TRAPHANDLER(name, num)                                                                  \
22         .text;                                                                                                          \
23         .globl name;            /* define global symbol for 'name' */   \
24         .type name, @function;  /* symbol type is function */           \
25         .align 2;               /* align function definition */                         \
26         name:                   /* function starts here */                                      \
27         pushl $(num);                                                                                           \
28         jmp _alltraps;                                                                                          \
29         .data;                                                                                                          \
30         .long name;                                                                                                     \
31         .long num
32
33 /* Use TRAPHANDLER_NOEC for traps where the CPU doesn't push an error code.
34  * It pushes a 0 in place of the error code, so the trap frame has the same
35  * format in either case.
36  */
37 #define TRAPHANDLER_NOEC(name, num)             \
38         .text;                                                          \
39         .globl name;                                            \
40         .type name, @function;                          \
41         .align 2;                                                       \
42         name:                                                           \
43         pushl $0;                                                       \
44         pushl $(num);                                           \
45         jmp _alltraps;                                          \
46         .data;                                                          \
47         .long name;                                                     \
48         .long num
49
50 /* Same as NOEC, but for IRQs instead.  num is the ISR number it is mapped to */
51 #define IRQ_HANDLER(name, num)                  \
52         .text;                                                          \
53         .globl name;                                            \
54         .type name, @function;                          \
55         .align 2;                                                       \
56         name:                                                           \
57         pushl $0;                                                       \
58         pushl $(num);                                           \
59         jmp _allirqs;                                           \
60         .data;                                                          \
61         .long name;                                                     \
62         .long num
63
64 /* Same as above, but takes a specific function to jump to.  See comments 
65  * below from _allirqs for details.
66  */
67 #define IRQ_HANDLER_SPEC(name, num, func)                                      \
68         .text;                                                                                                 \
69         .globl name;                                                                                   \
70         .type name, @function;                                                                 \
71         .align 2;                                                                                              \
72         name:                                                                                                  \
73         pushl $0;                                                                  \
74         pushl $(num);                                                              \
75         cld;                                                                       \
76         pushl %ds;                                                                 \
77         pushl %es;                                                                 \
78         pushal;                                                                    \
79         movw $GD_KD, %ax;                                                          \
80         movw %ax, %ds;                                                             \
81         movw %ax, %es;                                                             \
82         pushl %esp;                                                                \
83         movl $0, %ebp;                                                             \
84         call (func);                                                               \
85         popl %esp;                                                                 \
86         popal;                                                                     \
87         popl %es;                                                                  \
88         popl %ds;                                                                  \
89         addl $0x8, %esp;                                                           \
90         iret;                                                                      \
91         .data;                                                                     \
92         .long name;                                                                \
93         .long num
94
95 .data
96 .globl trap_tbl
97 trap_tbl:
98
99 /*
100  * Generate entry points for the different traps.
101  */
102 TRAPHANDLER_NOEC(ISR_divide_error, T_DIVIDE)
103 TRAPHANDLER_NOEC(ISR_debug_exceptions, T_DEBUG)
104 TRAPHANDLER_NOEC(ISR_NMI, T_NMI)
105 TRAPHANDLER_NOEC(ISR_breakpoint, T_BRKPT)
106 TRAPHANDLER_NOEC(ISR_overflow, T_OFLOW)
107 TRAPHANDLER_NOEC(ISR_bounds_check, T_BOUND)
108 TRAPHANDLER_NOEC(ISR_invalid_opcode, T_ILLOP)
109 TRAPHANDLER_NOEC(ISR_device_not_available, T_DEVICE)
110 /* supposedly, DF generates an error code, but the one time we've had a DF so
111  * far, it didn't.  eventually, this should probably be handled with a task gate
112  * it might have pushed a 0, but just the rest of the stack was corrupt
113  */
114 TRAPHANDLER_NOEC(ISR_double_fault, T_DBLFLT)
115 /* 9 reserved */
116 TRAPHANDLER(ISR_invalid_TSS, T_TSS)
117 TRAPHANDLER(ISR_segment_not_present, T_SEGNP)
118 TRAPHANDLER(ISR_stack_exception, T_STACK)
119 TRAPHANDLER(ISR_general_protection_fault, T_GPFLT)
120 TRAPHANDLER(ISR_page_fault, T_PGFLT)
121 /* 15 reserved */
122 TRAPHANDLER_NOEC(ISR_floating_point_error, T_FPERR)
123 TRAPHANDLER(ISR_alignment_check, T_ALIGN)
124 TRAPHANDLER_NOEC(ISR_machine_check, T_MCHK)
125 TRAPHANDLER_NOEC(ISR_simd_error, T_SIMDERR)
126 /* 20 - 31 reserved */
127 IRQ_HANDLER(IRQ0, 32)
128 IRQ_HANDLER(IRQ1, 33)
129 IRQ_HANDLER(IRQ2, 34)
130 IRQ_HANDLER(IRQ3, 35)
131 IRQ_HANDLER(IRQ4, 36)
132 IRQ_HANDLER(IRQ5, 37)
133 IRQ_HANDLER(IRQ6, 38)
134 IRQ_HANDLER(IRQ7, 39)
135 IRQ_HANDLER(IRQ8, 40)
136 IRQ_HANDLER(IRQ9, 41)
137 IRQ_HANDLER(IRQ10, 42)
138 IRQ_HANDLER(IRQ11, 43)
139 IRQ_HANDLER(IRQ12, 44)
140 IRQ_HANDLER(IRQ13, 45)
141 IRQ_HANDLER(IRQ14, 46)
142 IRQ_HANDLER(IRQ15, 47)
143 /* 25 general purpose vectors, for use by the LAPIC.  Can expand later. */
144 IRQ_HANDLER_SPEC(IRQ198, I_DEATH, __death) 
145 IRQ_HANDLER_SPEC(IRQ199, I_STARTCORE, __startcore) 
146 IRQ_HANDLER(IRQ200, 232)
147 IRQ_HANDLER(IRQ201, 233)
148 IRQ_HANDLER(IRQ202, 234)
149 IRQ_HANDLER(IRQ203, 235)
150 IRQ_HANDLER(IRQ204, 236)
151 IRQ_HANDLER(IRQ205, 237)
152 IRQ_HANDLER(IRQ206, 238)
153 IRQ_HANDLER(IRQ207, 239)
154 /* 0xf0 - start of the SMP_CALL IPIS */
155 IRQ_HANDLER(IRQ208, I_SMP_CALL0)
156 IRQ_HANDLER(IRQ209, I_SMP_CALL1)
157 IRQ_HANDLER(IRQ210, I_SMP_CALL2)
158 IRQ_HANDLER(IRQ211, I_SMP_CALL3)
159 IRQ_HANDLER(IRQ212, I_SMP_CALL4)
160 IRQ_HANDLER(IRQ213, 245)
161 IRQ_HANDLER(IRQ214, 246)
162 IRQ_HANDLER(IRQ215, 247)
163 IRQ_HANDLER(IRQ216, 248)
164 IRQ_HANDLER(IRQ217, 249)
165 IRQ_HANDLER(IRQ218, 250)
166 IRQ_HANDLER(IRQ219, 251)
167 IRQ_HANDLER(IRQ220, 252)
168 IRQ_HANDLER(IRQ221, 253)
169 IRQ_HANDLER(IRQ222, 254)
170 IRQ_HANDLER(IRQ223, 255) # I_TESTING in testing.c
171
172 /* Technically, these HANDLER entries do not need to be in numeric order */
173 TRAPHANDLER_NOEC(ISR_syscall, T_SYSCALL)
174 /* But make sure default is last!! */
175 TRAPHANDLER_NOEC(ISR_default, T_DEFAULT)
176
177 .data
178 .globl trap_tbl_end
179 trap_tbl_end:
180
181 /* Keep the exit paths of _alltraps, _allirqs, and sysenter_handler in sync
182  * with the corresponding pop_tf's.
183  */
184 .text
185 _alltraps:
186         cld
187         pushl %ds
188         pushl %es
189         pushal
190         movw $GD_KD, %ax                # data segments aren't accessible by default
191         movw %ax, %ds
192         movw %ax, %es
193         pushl %esp
194         movl $0, %ebp                   # so we can backtrace to this point
195         call trap
196         popl %esp
197         popal
198         popl %es
199         popl %ds
200         addl $0x8, %esp                 # skip trapno and err
201         iret
202
203 /* will need to think about when we reenable interrupts.  right now, iret does it,
204  * if the previous EFLAGS had interrupts enabled 
205  */
206 _allirqs:
207         cld
208         pushl %ds
209         pushl %es
210         pushal
211         movw $GD_KD, %ax                # data segments aren't accessible by default
212         movw %ax, %ds
213         movw %ax, %es
214         pushl %esp
215         movl $0, %ebp                   # so we can backtrace to this point
216         call irq_handler
217         popl %esp
218         popal
219         popl %es
220         popl %ds
221         addl $0x8, %esp                 # skip IRQ number and err (which is 0)
222         iret
223
224 .globl sysenter_handler;
225 .type sysenter_handler, @function;
226 sysenter_handler:
227         sti                                             # enable interrupts (things are sane here)
228         cld
229         pushfl                                  # save the eflags
230         pushl $0                                # these zeros keep the trapframe looking the same 
231         pushl $0                                # as when we receive a trap or interrupt
232         pushl $0                                # and CS == 0 lets the kernel know it was a sysenter
233         pushl $T_SYSCALL                # helps with print_trapframe
234         pushl %ds
235         pushl %es
236         pushal
237         movw $GD_KD, %ax
238         movw %ax, %ds
239         movw %ax, %es
240         pushl %esp
241         movl $0, %ebp                   # so we can backtrace to this point
242         call sysenter_callwrapper
243         popl %esp
244         popal
245         popl %es
246         popl %ds
247         addl $0x10, %esp                # pop T_SYSCALL and the three zeros
248         popfl                                   # restore EFLAGS
249         movl %ebp, %ecx
250         movl %esi, %edx
251         sti                                             # interrupts are turned off when starting a core
252         sysexit