MSI cleanup and IRQ routing
[akaros.git] / kern / arch / x86 / trapentry32.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 /* Only used in the kernel during SMP boot.  Send a LAPIC_EOI and iret. */
65 #define POKE_HANDLER(name, num)                 \
66         .text;                                                          \
67         .globl name;                                            \
68         .type name, @function;                          \
69         .align 2;                                                       \
70         name:;                                                          \
71         movl $0, (LAPIC_BASE + 0x0b0);      \
72         iret;                                                           \
73         .data;                                                          \
74         .long name;                                                     \
75         .long num
76
77 /* Same as above, but takes a specific function to jump to.  See comments
78  * below from _allirqs for details.
79  */
80 #define IRQ_HANDLER_SPEC(name, num, func)                                      \
81         .text;                                                                                                 \
82         .globl name;                                                                                   \
83         .type name, @function;                                                                 \
84         .align 2;                                                                                              \
85         name:                                                                                                  \
86         pushl $0;                                                                  \
87         pushl $(num);                                                              \
88         cld;                                                                       \
89         pushl %ds;                                                                 \
90         pushl %es;                                                                 \
91         pushl %fs;                                                                 \
92         pushl %gs;                                                                 \
93         pushal;                                                                    \
94         movw $0, %ax;                                                              \
95         movw %ax, %gs;                                                             \
96         movw %ax, %fs;                                                             \
97         movw $GD_KD, %ax;                                                          \
98         movw %ax, %ds;                                                             \
99         movw %ax, %es;                                                             \
100         pushl %esp;                                                                \
101         movl $0, %ebp;                                                             \
102         call (func);                                                               \
103         popl %esp;                                                                 \
104         popal;                                                                     \
105         popl %gs;                                                                  \
106         popl %fs;                                                                  \
107         popl %es;                                                                  \
108         popl %ds;                                                                  \
109         addl $0x8, %esp;                                                           \
110         iret;                                                                      \
111         .data;                                                                     \
112         .long name;                                                                \
113         .long num
114
115 .data
116 .globl trap_tbl
117 trap_tbl:
118
119 /*
120  * Generate entry points for the different traps.
121  */
122 TRAPHANDLER_NOEC(ISR_divide_error, T_DIVIDE)
123 TRAPHANDLER_NOEC(ISR_debug_exceptions, T_DEBUG)
124 TRAPHANDLER_NOEC(ISR_NMI, T_NMI)
125 TRAPHANDLER_NOEC(ISR_breakpoint, T_BRKPT)
126 TRAPHANDLER_NOEC(ISR_overflow, T_OFLOW)
127 TRAPHANDLER_NOEC(ISR_bounds_check, T_BOUND)
128 TRAPHANDLER_NOEC(ISR_invalid_opcode, T_ILLOP)
129 TRAPHANDLER_NOEC(ISR_device_not_available, T_DEVICE)
130 /* supposedly, DF generates an error code, but the one time we've had a DF so
131  * far, it didn't.  eventually, this should probably be handled with a task gate
132  * it might have pushed a 0, but just the rest of the stack was corrupt
133  */
134 TRAPHANDLER_NOEC(ISR_double_fault, T_DBLFLT)
135 /* 9 reserved */
136 TRAPHANDLER(ISR_invalid_TSS, T_TSS)
137 TRAPHANDLER(ISR_segment_not_present, T_SEGNP)
138 TRAPHANDLER(ISR_stack_exception, T_STACK)
139 TRAPHANDLER(ISR_general_protection_fault, T_GPFLT)
140 TRAPHANDLER(ISR_page_fault, T_PGFLT)
141 /* 15 reserved */
142 TRAPHANDLER_NOEC(ISR_floating_point_error, T_FPERR)
143 TRAPHANDLER(ISR_alignment_check, T_ALIGN)
144 TRAPHANDLER_NOEC(ISR_machine_check, T_MCHK)
145 TRAPHANDLER_NOEC(ISR_simd_error, T_SIMDERR)
146 /* 20 - 31 reserved */
147 IRQ_HANDLER(IRQ0, 32)
148 IRQ_HANDLER(IRQ1, 33)
149 IRQ_HANDLER(IRQ2, 34)
150 IRQ_HANDLER(IRQ3, 35)
151 IRQ_HANDLER(IRQ4, 36)
152 IRQ_HANDLER(IRQ5, 37)
153 IRQ_HANDLER(IRQ6, 38)
154 IRQ_HANDLER(IRQ7, 39)
155 IRQ_HANDLER(IRQ8, 40)
156 IRQ_HANDLER(IRQ9, 41)
157 IRQ_HANDLER(IRQ10, 42)
158 IRQ_HANDLER(IRQ11, 43)
159 IRQ_HANDLER(IRQ12, 44)
160 IRQ_HANDLER(IRQ13, 45)
161 IRQ_HANDLER(IRQ14, 46)
162 IRQ_HANDLER(IRQ15, 47)
163 /* IOAPIC/MSI vectors */
164 IRQ_HANDLER(IRQ16, 48)
165 IRQ_HANDLER(IRQ17, 49)
166 IRQ_HANDLER(IRQ18, 50)
167 IRQ_HANDLER(IRQ19, 51)
168 IRQ_HANDLER(IRQ20, 52)
169 IRQ_HANDLER(IRQ21, 53)
170 IRQ_HANDLER(IRQ22, 54)
171 IRQ_HANDLER(IRQ23, 55)
172 IRQ_HANDLER(IRQ24, 56)
173 IRQ_HANDLER(IRQ25, 57)
174 IRQ_HANDLER(IRQ26, 58)
175 IRQ_HANDLER(IRQ27, 59)
176 IRQ_HANDLER(IRQ28, 60)
177 IRQ_HANDLER(IRQ29, 61)
178 IRQ_HANDLER(IRQ30, 62)
179 IRQ_HANDLER(IRQ31, 63)
180 IRQ_HANDLER(IRQ32, 64)
181 IRQ_HANDLER(IRQ33, 65)
182 IRQ_HANDLER(IRQ34, 66)
183 IRQ_HANDLER(IRQ35, 67)
184 IRQ_HANDLER(IRQ36, 68)
185 IRQ_HANDLER(IRQ37, 69)
186 IRQ_HANDLER(IRQ38, 70)
187 IRQ_HANDLER(IRQ39, 71)
188 IRQ_HANDLER(IRQ40, 72)
189 IRQ_HANDLER(IRQ41, 73)
190 IRQ_HANDLER(IRQ42, 74)
191 IRQ_HANDLER(IRQ43, 75)
192 IRQ_HANDLER(IRQ44, 76)
193 IRQ_HANDLER(IRQ45, 77)
194 IRQ_HANDLER(IRQ46, 78)
195 IRQ_HANDLER(IRQ47, 79)
196 IRQ_HANDLER(IRQ48, 80)
197 IRQ_HANDLER(IRQ49, 81)
198 IRQ_HANDLER(IRQ50, 82)
199 IRQ_HANDLER(IRQ51, 83)
200 IRQ_HANDLER(IRQ52, 84)
201 IRQ_HANDLER(IRQ53, 85)
202 IRQ_HANDLER(IRQ54, 86)
203 IRQ_HANDLER(IRQ55, 87)
204 IRQ_HANDLER(IRQ56, 88)
205 IRQ_HANDLER(IRQ57, 89)
206 IRQ_HANDLER(IRQ58, 90)
207 IRQ_HANDLER(IRQ59, 91)
208 IRQ_HANDLER(IRQ60, 92)
209 IRQ_HANDLER(IRQ61, 93)
210 IRQ_HANDLER(IRQ62, 94)
211 IRQ_HANDLER(IRQ63, 95)
212 IRQ_HANDLER(IRQ64, 96)
213 IRQ_HANDLER(IRQ65, 97)
214 IRQ_HANDLER(IRQ66, 98)
215 IRQ_HANDLER(IRQ67, 99)
216 IRQ_HANDLER(IRQ68, 100)
217 IRQ_HANDLER(IRQ69, 101)
218 IRQ_HANDLER(IRQ70, 102)
219 IRQ_HANDLER(IRQ71, 103)
220 IRQ_HANDLER(IRQ72, 104)
221 IRQ_HANDLER(IRQ73, 105)
222 IRQ_HANDLER(IRQ74, 106)
223 IRQ_HANDLER(IRQ75, 107)
224 IRQ_HANDLER(IRQ76, 108)
225 IRQ_HANDLER(IRQ77, 109)
226 IRQ_HANDLER(IRQ78, 110)
227 IRQ_HANDLER(IRQ79, 111)
228 IRQ_HANDLER(IRQ80, 112)
229 IRQ_HANDLER(IRQ81, 113)
230 IRQ_HANDLER(IRQ82, 114)
231 IRQ_HANDLER(IRQ83, 115)
232 IRQ_HANDLER(IRQ84, 116)
233 IRQ_HANDLER(IRQ85, 117)
234 IRQ_HANDLER(IRQ86, 118)
235 IRQ_HANDLER(IRQ87, 119)
236 IRQ_HANDLER(IRQ88, 120)
237 IRQ_HANDLER(IRQ89, 121)
238 IRQ_HANDLER(IRQ90, 122)
239 IRQ_HANDLER(IRQ91, 123)
240 IRQ_HANDLER(IRQ92, 124)
241 IRQ_HANDLER(IRQ93, 125)
242 IRQ_HANDLER(IRQ94, 126)
243 IRQ_HANDLER(IRQ95, 127)
244 IRQ_HANDLER(IRQ96, 128)
245 IRQ_HANDLER(IRQ97, 129)
246 IRQ_HANDLER(IRQ98, 130)
247 IRQ_HANDLER(IRQ99, 131)
248 IRQ_HANDLER(IRQ100, 132)
249 IRQ_HANDLER(IRQ101, 133)
250 IRQ_HANDLER(IRQ102, 134)
251 IRQ_HANDLER(IRQ103, 135)
252 IRQ_HANDLER(IRQ104, 136)
253 IRQ_HANDLER(IRQ105, 137)
254 IRQ_HANDLER(IRQ106, 138)
255 IRQ_HANDLER(IRQ107, 139)
256 IRQ_HANDLER(IRQ108, 140)
257 IRQ_HANDLER(IRQ109, 141)
258 IRQ_HANDLER(IRQ110, 142)
259 IRQ_HANDLER(IRQ111, 143)
260 IRQ_HANDLER(IRQ112, 144)
261 IRQ_HANDLER(IRQ113, 145)
262 IRQ_HANDLER(IRQ114, 146)
263 IRQ_HANDLER(IRQ115, 147)
264 IRQ_HANDLER(IRQ116, 148)
265 IRQ_HANDLER(IRQ117, 149)
266 IRQ_HANDLER(IRQ118, 150)
267 IRQ_HANDLER(IRQ119, 151)
268 IRQ_HANDLER(IRQ120, 152)
269 IRQ_HANDLER(IRQ121, 153)
270 IRQ_HANDLER(IRQ122, 154)
271 IRQ_HANDLER(IRQ123, 155)
272 IRQ_HANDLER(IRQ124, 156)
273 IRQ_HANDLER(IRQ125, 157)
274 IRQ_HANDLER(IRQ126, 158)
275 IRQ_HANDLER(IRQ127, 159)
276 IRQ_HANDLER(IRQ128, 160)
277 IRQ_HANDLER(IRQ129, 161)
278 IRQ_HANDLER(IRQ130, 162)
279 IRQ_HANDLER(IRQ131, 163)
280 IRQ_HANDLER(IRQ132, 164)
281 IRQ_HANDLER(IRQ133, 165)
282 IRQ_HANDLER(IRQ134, 166)
283 IRQ_HANDLER(IRQ135, 167)
284 IRQ_HANDLER(IRQ136, 168)
285 IRQ_HANDLER(IRQ137, 169)
286 IRQ_HANDLER(IRQ138, 170)
287 IRQ_HANDLER(IRQ139, 171)
288 IRQ_HANDLER(IRQ140, 172)
289 IRQ_HANDLER(IRQ141, 173)
290 IRQ_HANDLER(IRQ142, 174)
291 IRQ_HANDLER(IRQ143, 175)
292 IRQ_HANDLER(IRQ144, 176)
293 IRQ_HANDLER(IRQ145, 177)
294 IRQ_HANDLER(IRQ146, 178)
295 IRQ_HANDLER(IRQ147, 179)
296 IRQ_HANDLER(IRQ148, 180)
297 IRQ_HANDLER(IRQ149, 181)
298 IRQ_HANDLER(IRQ150, 182)
299 IRQ_HANDLER(IRQ151, 183)
300 IRQ_HANDLER(IRQ152, 184)
301 IRQ_HANDLER(IRQ153, 185)
302 IRQ_HANDLER(IRQ154, 186)
303 IRQ_HANDLER(IRQ155, 187)
304 IRQ_HANDLER(IRQ156, 188)
305 IRQ_HANDLER(IRQ157, 189)
306 IRQ_HANDLER(IRQ158, 190)
307 IRQ_HANDLER(IRQ159, 191)
308 IRQ_HANDLER(IRQ160, 192)
309 IRQ_HANDLER(IRQ161, 193)
310 IRQ_HANDLER(IRQ162, 194)
311 IRQ_HANDLER(IRQ163, 195)
312 IRQ_HANDLER(IRQ164, 196)
313 IRQ_HANDLER(IRQ165, 197)
314 IRQ_HANDLER(IRQ166, 198)
315 IRQ_HANDLER(IRQ167, 199)
316 IRQ_HANDLER(IRQ168, 200)
317 IRQ_HANDLER(IRQ169, 201)
318 IRQ_HANDLER(IRQ170, 202)
319 IRQ_HANDLER(IRQ171, 203)
320 IRQ_HANDLER(IRQ172, 204)
321 IRQ_HANDLER(IRQ173, 205)
322 IRQ_HANDLER(IRQ174, 206)
323 IRQ_HANDLER(IRQ175, 207)
324 IRQ_HANDLER(IRQ176, 208)
325 IRQ_HANDLER(IRQ177, 209)
326 IRQ_HANDLER(IRQ178, 210)
327 IRQ_HANDLER(IRQ179, 211)
328 IRQ_HANDLER(IRQ180, 212)
329 IRQ_HANDLER(IRQ181, 213)
330 IRQ_HANDLER(IRQ182, 214)
331 IRQ_HANDLER(IRQ183, 215)
332 IRQ_HANDLER(IRQ184, 216)
333 IRQ_HANDLER(IRQ185, 217)
334 IRQ_HANDLER(IRQ186, 218)
335 IRQ_HANDLER(IRQ187, 219)
336 IRQ_HANDLER(IRQ188, 220)
337 IRQ_HANDLER(IRQ189, 221)
338 IRQ_HANDLER(IRQ190, 222)
339 IRQ_HANDLER(IRQ191, 223)
340 IRQ_HANDLER(IRQ192, 224)
341 IRQ_HANDLER(IRQ193, 225)
342 IRQ_HANDLER(IRQ194, 226)
343 IRQ_HANDLER(IRQ195, 227)
344 IRQ_HANDLER(IRQ196, 228)
345 IRQ_HANDLER(IRQ197, 229)
346
347 /* 25 general purpose vectors, for use by the LAPIC.  Can expand later. */
348 IRQ_HANDLER(IRQ198, I_TESTING) # used in testing.c
349 IRQ_HANDLER(IRQ199, 231)
350 IRQ_HANDLER(IRQ200, 232)
351 IRQ_HANDLER(IRQ201, 233)
352 IRQ_HANDLER(IRQ202, 234)
353 IRQ_HANDLER(IRQ203, 235)
354 IRQ_HANDLER(IRQ204, 236)
355 IRQ_HANDLER(IRQ205, 237)
356 IRQ_HANDLER(IRQ206, 238)
357 IRQ_HANDLER(IRQ207, 239)
358 /* 0xf0 - start of the SMP_CALL IPIS */
359 IRQ_HANDLER(IRQ208, I_SMP_CALL0)
360 IRQ_HANDLER(IRQ209, I_SMP_CALL1)
361 IRQ_HANDLER(IRQ210, I_SMP_CALL2)
362 IRQ_HANDLER(IRQ211, I_SMP_CALL3)
363 IRQ_HANDLER(IRQ212, I_SMP_CALL4)
364 IRQ_HANDLER(IRQ213, 245)
365 IRQ_HANDLER(IRQ214, 246)
366 IRQ_HANDLER(IRQ215, 247)
367 IRQ_HANDLER(IRQ216, 248)
368 IRQ_HANDLER(IRQ217, 249)
369 IRQ_HANDLER(IRQ218, 250)
370 IRQ_HANDLER(IRQ219, 251)
371 IRQ_HANDLER(IRQ220, 252)
372 IRQ_HANDLER(IRQ221, 253)
373 POKE_HANDLER(IRQ222, 254)
374 IRQ_HANDLER(IRQ223, I_KERNEL_MSG)
375
376 /* Technically, these HANDLER entries do not need to be in numeric order */
377 TRAPHANDLER_NOEC(ISR_syscall, T_SYSCALL)
378 /* But make sure default is last!! */
379 TRAPHANDLER_NOEC(ISR_default, T_DEFAULT)
380
381 .data
382 .globl trap_tbl_end
383 trap_tbl_end:
384
385 /* Keep the exit paths of _alltraps, _allirqs, and sysenter_handler in sync
386  * with the corresponding pop_tf's.
387  */
388 .text
389 _alltraps:
390         cld
391         pushl %ds
392         pushl %es
393         pushl %fs
394         pushl %gs
395         pushal
396         movw $0, %ax;
397         movw %ax, %gs;
398         movw %ax, %fs;
399         movw $GD_KD, %ax                # data segments aren't accessible by default
400         movw %ax, %ds
401         movw %ax, %es
402         pushl %esp
403         movl $0, %ebp                   # so we can backtrace to this point
404         call trap
405         popl %esp
406         popal
407         popl %gs
408         popl %fs
409         popl %es
410         popl %ds
411         addl $0x8, %esp                 # skip trapno and err
412         iret
413
414 /* will need to think about when we reenable interrupts.  right now, iret does it,
415  * if the previous EFLAGS had interrupts enabled
416  */
417 _allirqs:
418         cld
419         pushl %ds
420         pushl %es
421         pushl %fs
422         pushl %gs
423         pushal
424         movw $0, %ax;
425         movw %ax, %gs;
426         movw %ax, %fs;
427         movw $GD_KD, %ax                # data segments aren't accessible by default
428         movw %ax, %ds
429         movw %ax, %es
430         pushl %esp
431         movl $0, %ebp                   # so we can backtrace to this point
432         call handle_irq
433         popl %esp
434         popal
435         popl %gs
436         popl %fs
437         popl %es
438         popl %ds
439         addl $0x8, %esp                 # skip IRQ number and err (which is 0)
440         iret
441
442 .globl sysenter_handler;
443 .type sysenter_handler, @function;
444 # All of the pushl zeros are to keep the trap frame looking the same as when we
445 # receive a trap or an interrupt
446 sysenter_handler:
447         cld
448         pushl $0                                # ss
449         pushl $0                                # esp
450         pushfl                                  # eflags
451         pushl $0                                # CS == 0 lets the kernel know it was a sysenter        
452         pushl $0                                # eip
453         pushl $0                                # err 
454         pushl $T_SYSCALL                # helps with print_trapframe
455         pushl %ds
456         pushl %es
457         pushl %fs
458         pushl %gs
459         pushal
460         movw $0, %ax;
461         movw %ax, %gs;
462         movw %ax, %fs;
463         movw $GD_KD, %ax
464         movw %ax, %ds
465         movw %ax, %es
466         pushl %esp
467         movl $0, %ebp                   # so we can backtrace to this point
468         call sysenter_callwrapper
469         popl %esp
470         popal
471         popl %gs
472         popl %fs
473         popl %es
474         popl %ds
475         addl $0x10, %esp                # pop T_SYSCALL and the three zeros
476         popfl                                   # restore EFLAGS (and usually enables interrupts!)
477         movl %ebp, %ecx
478         sti                                             # interrupts are turned off when starting a core
479         sysexit