edit readme
[lunaix-os.git] / lunaix-os / kernel / asm / x86 / interrupt.S
1 #define __ASM__
2 #include <arch/x86/interrupts.h>
3 #include <lunaix/common.h>
4 #define __ASM_INTR_DIAGNOSIS
5
6 .macro isr_template vector, no_error_code=1
7     .global _asm_isr\vector
8     .type _asm_isr\vector, @function
9     _asm_isr\vector:
10         .if \no_error_code
11             pushl $0x0
12         .endif
13         pushl $\vector
14         jmp interrupt_wrapper
15 .endm
16
17 #ifdef __ASM_INTR_DIAGNOSIS
18 .section .bss
19     .global debug_resv
20     debug_resv:
21         .skip 16
22 #endif
23
24 .section .text
25     isr_template FAULT_DIVISION_ERROR
26     isr_template FAULT_GENERAL_PROTECTION, no_error_code=0
27     isr_template FAULT_PAGE_FAULT, no_error_code=0
28
29     isr_template LUNAIX_SYS_PANIC
30     isr_template LUNAIX_SYS_CALL
31
32     isr_template APIC_ERROR_IV
33     isr_template APIC_LINT0_IV
34     isr_template APIC_TIMER_IV
35     isr_template APIC_SPIV_IV
36     isr_template RTC_TIMER_IV
37     isr_template PC_KBD_IV
38
39     interrupt_wrapper:
40         /*
41          Stack layout
42     msa:   [ss]
43            [esp]
44            eflags
45            cs
46            eip
47            err_code   
48            vector     > offset = 28 + 16 + 4 = 48
49            esp
50            gs
51            fs
52            es
53            ds         > offset = 7 * 4 = 28
54            esi
55            ebp
56            edi
57            edx
58            ecx
59            ebx
60     lsa:   eax        > offset = 0
61
62             las: Least Significant Address
63             msa: Most Significant Address
64         */
65         pushl %esp
66
67         subl $16, %esp
68         movw %gs, 12(%esp)
69         movw %fs,  8(%esp)
70         movw %es,  4(%esp)
71         movw %ds,   (%esp)
72
73         pushl %esi
74         pushl %ebp
75         pushl %edi
76         pushl %edx
77         pushl %ecx
78         pushl %ebx
79         pushl %eax
80
81         movl 60(%esp), %eax   /* 取出 %cs */
82         andl $0x3, %eax          /* 判断 RPL */
83         jz 1f
84
85         movw $KDATA_SEG, %ax    /* 如果从用户模式转来,则切换至内核数据段 */
86         movw %ax, %gs
87         movw %ax, %fs
88         movw %ax, %ds
89         movw %ax, %es
90
91     1:
92         movl %esp, %eax
93         andl $0xfffffff0, %esp
94         subl $16, %esp
95         movl %eax, (%esp)
96
97         call intr_handler
98
99         movl (%esp), %eax
100
101     .global soft_iret
102     soft_iret:
103         movl %eax, %esp
104
105         popl %eax
106         popl %ebx
107         popl %ecx
108         popl %edx
109         popl %edi
110         popl %ebp
111         popl %esi
112         
113         movw   (%esp), %ds
114         movw  4(%esp), %es
115         movw  8(%esp), %fs
116         movw 12(%esp), %gs
117
118         movl 16(%esp), %esp
119
120         addl $8, %esp
121
122 #ifdef __ASM_INTR_DIAGNOSIS
123         pushl %eax
124         movl 4(%esp), %eax
125         movl %eax, debug_resv
126         popl %eax
127 #endif
128         iret