Set TFS_DIR by default when the TFS_DIR env is not set
[thunix.git] / kernel / asm.s
bloba77cf0bfde7f990c91f8840098425abc58356bb8
1 /* Yeah, i finally figure it out with a half day debugging.
2 * when an interrupt happened with no pri changed, process wouldn't
3 * push the OLD SS and OLD ESP in the following stack fragment. And
4 * that also happened to WITH_ERROR_CODE interrupt.
6 * So, if when we at pri ZERO, and do a var_a = var_b / 0 that ivoke
7 * a divide_error interrupt, and it just push the the flag regsiter and
8 * and cs register with eip where the interrupt happened. There is NO
9 * OLD SS and OLD ESP, then the final handler die() will put wrong
10 * information that the the value of SS:ESP is random and no rule.
14 /*
15 * no ERROR_code fragment
16 +--------+--------+
17 | | old ss |
18 +--------+--------+
19 | old esp |
20 +--------+--------+
21 | old eflags |
22 +--------+--------+
23 | | cs |
24 +--------+--------+
25 | eip |0x34
26 +--------+--------+
27 | c_fun_addr |0x30
28 +--------+--------+
29 | eax |0x2c
30 +--------+--------+
31 | ecx |0x28
32 +--------+--------+
33 | edx |0x24
34 +--------+--------+
35 | ebx |0x20
36 +--------+--------+
37 | esi |0x1c
38 +--------+--------+
39 | edi |0x18
40 +--------+--------+
41 | ebp |0x14
42 +--------+--------+
43 | | ds |0x10
44 +--------+--------+
45 | | es |0x0c
46 +--------+--------+
47 | | fs |0x08
48 +--------+--------+
49 | error_code(=0) |0x04 that's the para needed to pass to handler function
50 +--------+--------+
51 | ptr_to_eip |0x00 the protype of handler is do_xxx(eip_addr, err_code)
52 +--------+--------+
55 .globl divide_error
56 divide_error:
57 pushl $do_divide_error
59 no_error_code:
60 /* push all the reg first to protect data */
61 pushl %eax
62 pushl %ecx
63 pushl %edx
64 pushl %ebx
65 pushl %edi
66 pushl %esi
67 pushl %ebp
68 pushl %ds
69 pushl %es
70 pushl %fs
72 pushl $0 # error code
73 lea 0x30(%esp), %eax # get the addr of eip as para ofdo_xx
74 pushl %eax
75 movl 0x30(%esp), %eax # another para of do_xxx
76 movl $0x10,%edx
77 movw %dx,%ds
78 movw %dx,%es
79 movw %dx,%fs
80 call *%eax
81 addl $8,%esp # pop the two para
83 popl %fs
84 popl %es
85 popl %ds
86 popl %ebp
87 popl %esi
88 popl %edi
89 popl %ebx
90 popl %edx
91 popl %ecx
92 popl %eax
94 addl $4,%esp # pop the handler address
95 iret
97 .globl debug
98 debug:
99 pushl $do_int3 # _do_debug
100 jmp no_error_code
102 .globl nmi
103 nmi:
104 pushl $do_nmi
105 jmp no_error_code
107 .globl int3
108 int3:
109 pushl $do_int3
110 jmp no_error_code
112 .globl overflow
113 overflow:
114 pushl $do_overflow
115 jmp no_error_code
117 .globl bounds
118 bounds:
119 pushl $do_bounds
120 jmp no_error_code
122 .globl invalid_op
123 invalid_op:
124 pushl $do_invalid_op
125 jmp no_error_code
127 .globl coprocessor_segment_overrun
128 coprocessor_segment_overrun:
129 pushl $do_coprocessor_segment_overrun
130 jmp no_error_code
132 .globl reserved
133 reserved:
134 pushl $do_reserved
135 jmp no_error_code
137 #irq13:
138 # pushl %eax
139 # xorb %al,%al
140 # outb %al,$0xF0
141 # movb $0x20,%al
142 # outb %al,$0x20
143 # jmp 1f
144 #1: jmp 1f
145 #1: outb %al,$0xA0
146 # popl %eax
147 # jmp coprocessor_error
152 * with ERROR_code fragment
153 +--------+--------+
154 | | old ss |
155 +--------+--------+
156 | old eps |
157 +--------+--------+
158 | old eflags |
159 +--------+--------+
160 | | cs |
161 +--------+--------+
162 | eip |0x38
163 +--------+--------+
164 | error_code |0x34
165 +--------+--------+
166 | c_fun_addr |0x30
167 +--------+--------+
168 | eax |0x2c
169 +--------+--------+
170 | ecx |0x28
171 +--------+--------+
172 | edx |0x24
173 +--------+--------+
174 | ebx |0x20
175 +--------+--------+
176 | edi |0x1c
177 +--------+--------+
178 | esi |0x18
179 +--------+--------+
180 | ebp |0x14
181 +--------+--------+
182 | | ds |0x10
183 +--------+--------+
184 | | es |0x0c
185 +--------+--------+
186 | | fs |0x08
187 +--------+--------+
188 | error_code |0x04 that's the para needed to pass to handler function
189 +--------+--------+
190 | ptr_to_eip |0x00 the protype of handler is do_xxx(eip_addr, err_code)
191 +--------+--------+
195 .globl double_fault
196 double_fault:
197 pushl $do_double_fault
198 error_code:
200 pushl %eax
201 pushl %ecx
202 pushl %edx
203 pushl %ebx
204 pushl %edi
205 pushl %esi
206 pushl %ebp
207 pushl %ds
208 pushl %es
209 pushl %fs
211 movl 0x30(%esp), %eax # erro code
212 pushl %eax
213 lea 0x34(%esp), %eax # ptr to eip
214 pushl %eax
216 movl $0x10,%eax
217 movw %ax,%ds
218 movw %ax,%es
219 movw %ax,%fs
220 movl 0x30(%esp), %eax
221 call *%eax
222 addl $8,%esp
223 pop %fs
224 pop %es
225 pop %ds
226 popl %ebp
227 popl %esi
228 popl %edi
229 popl %ebx
230 popl %edx
231 popl %ecx
232 popl %eax
234 addl $8, %esp
235 iret
237 .globl invalid_TSS
238 invalid_TSS:
239 pushl $do_invalid_TSS
240 jmp error_code
242 .globl segment_not_present
243 segment_not_present:
244 pushl $do_segment_not_present
245 jmp error_code
247 .globl stack_segment
248 stack_segment:
249 pushl $do_stack_segment
250 jmp error_code
252 .globl general_protection
253 general_protection:
254 pushl $do_general_protection
255 jmp error_code
258 .globl read_eip
259 read_eip:
260 pop %eax
261 jmp *%eax
264 /* i'm tried to make the timer work correct, so i move the
265 interrupt handle here. hope it works. :)
268 .globl timer_interrupt
269 timer_interrupt:
270 pushl %eax
271 pushl %ecx
272 pushl %edx
273 pushl %ebx
274 pushl %edi
275 pushl %esi
276 pushl %ebp
277 pushl %ds
278 pushl %es
279 pushl %fs
281 incl timer_ticks
282 movb $0x20,%al # EOI to interrupt controller #1
283 outb %al,$0x20
285 call do_timer
287 pop %fs
288 pop %es
289 pop %ds
290 popl %ebp
291 popl %esi
292 popl %edi
293 popl %ebx
294 popl %edx
295 popl %ecx
296 popl %eax
298 iret
300 .globl floppy_interrupt
301 floppy_interrupt:
302 pushl %eax
303 pushl %ecx
304 pushl %edx
305 pushl %ebx
306 pushl %edi
307 pushl %esi
308 pushl %ebp
309 pushl %ds
310 pushl %es
311 pushl %fs
313 call do_floppy
315 pop %fs
316 pop %es
317 pop %ds
318 popl %ebp
319 popl %esi
320 popl %edi
321 popl %ebx
322 popl %edx
323 popl %ecx
324 popl %eax
326 iret
328 __NR_syscall = 0x03
330 .globl syscall_interrupt
331 syscall_interrupt:
332 pushl %eax
333 pushl %ecx
334 pushl %edx
335 pushl %ebx
336 pushl %edi
337 pushl %esi
338 pushl %ebp
339 pushl %ds
340 pushl %es
341 pushl %fs
343 cmpl $__NR_syscall, %eax
344 ja bad_syscall
346 pushl %edx
347 pushl %ecx
348 pushl %ebx
349 call *syscall_table(,%eax,4)
350 addl $12, %esp
352 syscall_ret:
353 pop %fs
354 pop %es
355 pop %ds
356 popl %ebp
357 popl %esi
358 popl %edi
359 popl %ebx
360 popl %edx
361 popl %ecx
362 popl %eax
364 iret
366 bad_syscall:
367 movl $-38, %eax # ENOSYS
368 jmp syscall_ret