rev |
line source |
nuclear@54
|
1 #define ASM
|
nuclear@54
|
2 #include "segm.h"
|
nuclear@54
|
3
|
nuclear@11
|
4 .data
|
nuclear@11
|
5 .align 4
|
nuclear@11
|
6 .short 0
|
nuclear@11
|
7 /* memory reserved for set_idt */
|
nuclear@11
|
8 lim:.short 0
|
nuclear@11
|
9 addr:.long 0
|
nuclear@11
|
10
|
nuclear@11
|
11 .text
|
nuclear@11
|
12 /* set_idt(uint32_t addr, uint16_t limit)
|
nuclear@11
|
13 * loads the IDTR with the new address and limit for the IDT */
|
nuclear@11
|
14 .globl set_idt
|
nuclear@11
|
15 set_idt:
|
nuclear@11
|
16 movl 4(%esp), %eax
|
nuclear@11
|
17 movl %eax, (addr)
|
nuclear@11
|
18 movw 8(%esp), %ax
|
nuclear@11
|
19 movw %ax, (lim)
|
nuclear@11
|
20 lidt (lim)
|
nuclear@11
|
21 ret
|
nuclear@11
|
22
|
nuclear@25
|
23 /* get_intr_state()
|
nuclear@25
|
24 * returns 1 if interrutps are enabled, 0 if disabled */
|
nuclear@25
|
25 .globl get_intr_state
|
nuclear@25
|
26 get_intr_state:
|
nuclear@25
|
27 pushf
|
nuclear@25
|
28 popl %eax
|
nuclear@25
|
29 shr $9, %eax /* bit 9 of eflags is IF */
|
nuclear@25
|
30 andl $1, %eax
|
nuclear@25
|
31 ret
|
nuclear@25
|
32
|
nuclear@25
|
33 /* set_intr_state(int state)
|
nuclear@25
|
34 * enables interrupts if the argument is non-zero, disables them otherwise */
|
nuclear@25
|
35 .globl set_intr_state
|
nuclear@25
|
36 set_intr_state:
|
nuclear@25
|
37 cmpl $0, 4(%esp)
|
nuclear@25
|
38 jz 0f
|
nuclear@25
|
39 sti
|
nuclear@25
|
40 ret
|
nuclear@25
|
41 0: cli
|
nuclear@25
|
42 ret
|
nuclear@25
|
43
|
nuclear@25
|
44
|
nuclear@11
|
45 /* interrupt entry with error code macro
|
nuclear@11
|
46 * this macro generates an interrupt entry point for the
|
nuclear@11
|
47 * exceptions which include error codes in the stack frame
|
nuclear@11
|
48 */
|
nuclear@11
|
49 .macro ientry_err n name
|
nuclear@11
|
50 .globl intr_entry_\name
|
nuclear@11
|
51 intr_entry_\name:
|
nuclear@11
|
52 pushl $\n
|
nuclear@11
|
53 jmp intr_entry_common
|
nuclear@11
|
54 .endm
|
nuclear@11
|
55
|
nuclear@11
|
56 /* interrupt entry without error code macro
|
nuclear@11
|
57 * this macro generates an interrupt entry point for the interrupts
|
nuclear@11
|
58 * and exceptions which do not include error codes in the stack frame
|
nuclear@11
|
59 * it pushes a dummy error code (0), to make the stack frame identical
|
nuclear@11
|
60 */
|
nuclear@11
|
61 .macro ientry_noerr n name
|
nuclear@11
|
62 .globl intr_entry_\name
|
nuclear@11
|
63 intr_entry_\name:
|
nuclear@11
|
64 pushl $0
|
nuclear@11
|
65 pushl $\n
|
nuclear@11
|
66 jmp intr_entry_common
|
nuclear@11
|
67 .endm
|
nuclear@11
|
68
|
nuclear@11
|
69 /* common code used by all entry points. calls dispatch_intr()
|
nuclear@11
|
70 * defined in intr.c
|
nuclear@11
|
71 */
|
nuclear@11
|
72 .extern dispatch_intr
|
nuclear@11
|
73 intr_entry_common:
|
nuclear@54
|
74 /* save the current data segment selectors */
|
nuclear@54
|
75 pushl %gs
|
nuclear@54
|
76 pushl %fs
|
nuclear@54
|
77 pushl %es
|
nuclear@54
|
78 pushl %ds
|
nuclear@54
|
79 /* save general purpose registers */
|
nuclear@11
|
80 pusha
|
nuclear@54
|
81 /* if we entered from userspace ss and cs is set correctly, but
|
nuclear@54
|
82 * we must make sure all the other selectors are set to the
|
nuclear@54
|
83 * kernel data segment */
|
nuclear@55
|
84 mov %ss, %eax
|
nuclear@55
|
85 mov %eax, %ds
|
nuclear@55
|
86 mov %eax, %es
|
nuclear@55
|
87 mov %eax, %fs
|
nuclear@55
|
88 mov %eax, %gs
|
nuclear@11
|
89 call dispatch_intr
|
nuclear@50
|
90 intr_ret_local:
|
nuclear@54
|
91 /* restore general purpose registers */
|
nuclear@11
|
92 popa
|
nuclear@54
|
93 /* restore data segment selectors */
|
nuclear@54
|
94 popl %ds
|
nuclear@54
|
95 popl %es
|
nuclear@54
|
96 popl %fs
|
nuclear@54
|
97 popl %gs
|
nuclear@11
|
98 /* remove error code and intr num from stack */
|
nuclear@11
|
99 add $8, %esp
|
nuclear@11
|
100 iret
|
nuclear@11
|
101
|
nuclear@50
|
102 /* intr_ret is called by context_switch to return from the kernel
|
nuclear@50
|
103 * to userspace. The argument is a properly formed intr_frame
|
nuclear@50
|
104 * structure with the saved context of the new task.
|
nuclear@50
|
105 *
|
nuclear@50
|
106 * First thing to do is remove the return address pointing back
|
nuclear@50
|
107 * to context_switch, which then leaves us with a proper interrupt
|
nuclear@50
|
108 * stack frame, so we can jump right in the middle of the regular
|
nuclear@50
|
109 * interrupt return code above.
|
nuclear@50
|
110 */
|
nuclear@50
|
111 .globl intr_ret
|
nuclear@50
|
112 intr_ret:
|
nuclear@50
|
113 add $4, %esp
|
nuclear@50
|
114 jmp intr_ret_local
|
nuclear@50
|
115
|
nuclear@11
|
116 /* by including interrupts.h with ASM defined, the macros above
|
nuclear@11
|
117 * are expanded to generate all required interrupt entry points
|
nuclear@11
|
118 */
|
nuclear@11
|
119 #include <interrupts.h>
|