-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathentry.S
163 lines (149 loc) · 3.53 KB
/
entry.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
* entry.S - Entry point to system mode from user mode
*/
#include <asm.h>
#include <segment.h>
/**************************************************/
/**** Save & Restore ******************************/
/** **/
/** When we change to privilege level 0 (kernel) **/
/** (through an interrupt, a system call, an **/
/** exception ...) we must save the state of the **/
/** currently running task (save). **/
/** **/
/** Stack layout in 'systemCall': **/
/** **/
/** 0(%esp) - %ebx \ **/
/** 4(%esp) - %ecx | **/
/** 8(%esp) - %edx | **/
/** C(%esp) - %esi | Register saved **/
/** 10(%esp) - %edi | by 'save' **/
/** 14(%esp) - %ebp | **/
/** 18(%esp) - %eax | **/
/** 1C(%esp) - %ds | **/
/** 20(%esp) - %es | **/
/** 24(%esp) - %fs | **/
/** 28(%esp) - %gs / **/
/** 2C(%esp) - %eip \ **/
/** 30(%esp) - %cs | **/
/** 34(%esp) - %eflags | Return context saved **/
/** 38(%esp) - %oldesp | by the processor. **/
/** 3C(%esp) - %oldss / **/
/** **/
/**************************************************/
#define SAVE_ALL \
pushl %gs; \
pushl %fs; \
pushl %es; \
pushl %ds; \
pushl %eax; \
pushl %ebp; \
pushl %edi; \
pushl %esi; \
pushl %edx; \
pushl %ecx; \
pushl %ebx; \
movl $__KERNEL_DS, %edx; \
movl %edx, %ds; \
movl %edx, %es
#define RESTORE_ALL \
popl %ebx;\
popl %ecx;\
popl %edx;\
popl %esi;\
popl %edi;\
popl %ebp;\
popl %eax;\
popl %ds; \
popl %es; \
popl %fs; \
popl %gs
#define EOI \
movb $0x20, %al; \
outb %al, $0x20;
ENTRY(writeMsr)
push %ebp
movl %esp, %ebp
movl 8(%ebp), %ecx
movl 12(%ebp), %eax
movl $0, %edx
wrmsr
pop %ebp
ret
ENTRY(keyboard_handler)
SAVE_ALL;
EOI;
call update_entry_system;
call keyboard_routine;
call update_leave_system;
RESTORE_ALL;
iret;
ENTRY(system_call_handler)
SAVE_ALL;
cmpl $0, %eax;
jl error;
cmpl $MAX_SYSCALL, %eax;
jg error;
call *sys_call_table(,%eax,4);
jmp fin;
error:
movl $-38, %eax;
fin: movl %eax, 18(%esp);
RESTORE_ALL;
iret;
ENTRY(syscall_handler_sysenter)
push $__USER_DS;
push %ebp;
pushfl
push $__USER_CS
push 4(%ebp)
SAVE_ALL
push %eax
call update_entry_system
pop %eax
cmpl $0, %eax
jl sysenter_error
cmpl $MAX_SYSCALL, %eax
jg sysenter_error
call *sys_call_table(,%eax,0x04)
jmp sysenter_fin
sysenter_error:
movl $-38, %eax
sysenter_fin:
movl %eax, 0x18(%esp)
call update_leave_system;
RESTORE_ALL
movl (%esp), %edx
movl 12(%esp), %ecx
sti
sysexit
ENTRY(clock_handler)
SAVE_ALL;
EOI;
call update_entry_system;
call clock_routine;
call update_leave_system;
RESTORE_ALL;
iret;
ENTRY(task_switch)
pushl %ebp;
movl %esp, %ebp;
pushl %esi;
pushl %edi;
pushl %ebx;
pushl 8(%ebp);
call inner_task_switch;
addl $4, %esp;
popl %ebx;
popl %edi;
popl %esi;
movl %ebp, %esp;
popl %ebp;
ret;
ENTRY(setEsp)
movl 4(%esp), %esp
popl %ebp;
ret;
ENTRY(getEbp)
movl %ebp, %eax
ret;