feat: pgid support
[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     .global soft_iret
100     soft_iret:
101         popl %esp
102
103         popl %eax
104         popl %ebx
105         popl %ecx
106         popl %edx
107         popl %edi
108         popl %ebp
109         popl %esi
110         
111         movw   (%esp), %ds
112         movw  4(%esp), %es
113         movw  8(%esp), %fs
114         movw 12(%esp), %gs
115
116         movl 16(%esp), %esp
117
118         addl $8, %esp
119
120 #ifdef __ASM_INTR_DIAGNOSIS
121         pushl %eax
122         movl 4(%esp), %eax
123         movl %eax, debug_resv
124         popl %eax
125 #endif
126         iret