2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
7 Full low-level interrupt core. Provides AmigaOS-like preemptive
12 Save/restore macros. These are used to save scratch registers
13 while entering interrupt. Inside interrupt if you cover it with
14 this macros you may use freely these registers. All other HAS to
18 #include "aros/i386/asm.h"
19 #include <asm/segments.h>
27 movl $KERNEL_DS,%edx; \
31 #define RESTORE_REGS \
46 Save/restore all registers. These macros are used mostly inside Switch
60 movl $KERNEL_DS,%edx; \
78 .globl Exec_Permit_Supervisor
79 .type Exec_Permit_Supervisor,@function
81 Exec_Permit_Supervisor:
82 testl $3,4(%esp) /* Check whether called from user mode */
83 jne Exec_Schedule /* Call Schedule() if yes */
84 iret /* Exit otherwise */
88 .type sys_Supervisor,@function
90 sys_Supervisor: addl $4,%esp /* Remove caller address */
91 RESTORE_REGS /* Restore all registers */
92 addl $4,%esp /* Remove call code */
93 jmp *%edx /* Call user code */
96 .globl exec_SuperState
97 .type exec_SuperState,@function
99 xorl %eax, %eax /* clear eax */
100 testl $0x3000,0x08(%esp) /* check in save EFLAGS if called from SU mode */
101 je exec_SS_IRET /* if yes we don't need this routine */
102 movl %esp,%eax /* return int handler stack */
103 movl 0x0c(%eax),%esp /* use user stack */
104 pushl (%eax) /* push return address */
105 ret /* return after Supervisor() call */
110 /* for UserState() see userstate.c */
113 System call routine. It executes given C code through 'int $0x80' call.
114 The function code is specified in %eax register. Functions available are
117 0 -> execute Cause() routine
118 -1 -> execute ColdReboot() routine
119 -2 -> execute Supervisor() routine
121 Values not defined here are ignored.
123 After executing C function, the ExitIntr is issued. If the interrupt was
124 called from user mode and task switching is allowed, Schedule() is started.
129 .globl Exec_SystemCall
130 .type Exec_SystemCall,@function
132 Exec_SystemCall: negl %eax
137 call *sys_call_table(,%eax,4)
138 movl %eax,R_eax(%esp)
140 restore_all: RESTORE_REGS
146 .type Exec_ExitIntr,@function
148 Exec_ExitIntr: cmpw $KERNEL_DS,R_ds(%esp)
152 testw $0x20,SysFlags(%eax) /* SFF_SoftInt set? */
153 je Exec_ExitIntr_NoSoftInts
159 Exec_ExitIntr_NoSoftInts:
160 cmpb $0,TDNestCnt(%eax)
162 testw $0x80,AttnResched(%eax)
168 .type Exec_Schedule,@function
170 Exec_Schedule: pushl $0
172 Exec_Schedule_x: cli /* stegerg: added -> CHECKME */
174 andw $0xff7f,AttnResched(%edx)
175 movl ThisTask(%edx),%eax
176 testb $TF_EXCEPT,tc_Flags(%eax)
179 lea TaskReady(%edx),%ecx
180 cmpl lh_TailPred(%ecx),%ecx
183 movl lh_Head(%ecx),%ecx
184 movb ln_Pri(%ecx),%cl
185 cmpb ln_Pri(%eax),%cl
188 #warning TODO: Implement tasks Time Slices
190 testw $0x2000,SysFlags(%edx)
195 movb $TS_READY,tc_State(%eax)
196 lea TaskReady(%edx),%ecx
203 movl Switch(%edx),%eax
204 movl %eax,R_param(%esp)
209 This routine does a task switch. It sores the context of
210 running task and calls dispatcher.
212 The context is stored in special place inside Task struncture.
217 .type Exec_Switch,@function
218 Exec_Switch: cli /* Disable all interrupts */
220 SAVE_ALL /* Save context */
222 movl 4,%eax /* get ExecBase->ThisTask */
223 movl ThisTask(%eax),%eax
225 movl %esp,%esi /* Copy the context from stack */
226 movl tc_ETask(%eax),%edi /* into task->tc_ETask->iet_Context */
227 movl iet_Context(%edi),%edi
232 movl $Exec_Restore_Gene,%edi
234 Exec_Switch_Common: movl 4,%ebp
235 movb IDNestCnt(%ebp),%al
236 movb $-1,IDNestCnt(%ebp)
238 cli /* stegerg: was "sti" -> CHECKME */
240 movl ThisTask(%ebp),%ebx
241 movb %al,tc_IDNestCnt(%ebx)
242 movl 48(%esp),%eax /* Get USP */
243 movl %eax,tc_SPReg(%ebx)
245 testb $TF_SWITCH,tc_Flags(%ebx)
248 movl tc_Switch(%ebx),%eax
253 .globl Exec_Switch_FPU
254 .type Exec_Switch_FPU,@function
259 movl ThisTask(%eax),%eax
262 movl tc_ETask(%eax),%edi
263 movl iet_Context(%edi),%edi
271 movl $Exec_Restore_FPU,%edi
272 jmp Exec_Switch_Common
275 .globl Exec_Switch_SSE
276 .type Exec_Switch_SSE,@function
281 movl ThisTask(%eax),%eax
284 movl tc_ETask(%eax),%edi
285 movl iet_Context(%edi),%edi
294 movl $Exec_Restore_SSE,%edi
295 jmp Exec_Switch_Common
298 .globl Exec_Dispatch_SSE
299 .type Exec_Dispatch_SSE,@function
301 Exec_Dispatch_SSE: SAVE_ALL
302 movl $Exec_Restore_SSE,%edi
303 jmp Exec_Dispatch_com
306 .globl Exec_Dispatch_FPU
307 .type Exec_Dispatch_FPU,@function
309 Exec_Dispatch_FPU: SAVE_ALL
310 movl $Exec_Restore_FPU,%edi
311 jmp Exec_Dispatch_com
315 .type Exec_Dispatch,@function
317 Exec_Dispatch: SAVE_ALL
318 movl $Exec_Restore_Gene,%edi
319 Exec_Dispatch_com: movl 4,%ebp
320 movb $-1,IDNestCnt(%ebp)
324 leal TaskReady(%ebp),%eax
325 movl lh_Head(%eax),%ecx
326 movl ln_Succ(%ecx),%edx
331 orw $0x80,AttnResched(%ebp)
336 testw $0x20,SysFlags(%ebp) /* SFF_SoftInt set? */
343 1: movl %edx,lh_Head(%eax)
344 movl %eax,ln_Pred(%edx)
346 movl %ecx,ThisTask(%ebp)
348 /* Handle Quantum fields!!!! */
350 movw Quantum(%ebp),%ax
351 movw %ax,Elapsed(%ebp)
353 andw $~0x2000,SysFlags(%ebp)
354 movb $TS_RUN,tc_State(%ecx)
355 movb tc_IDNestCnt(%ecx),%al
356 movb %al,IDNestCnt(%ebp)
357 cmpb $0,IDNestCnt(%ebp)
361 testb $TF_EXCEPT | TF_LAUNCH,tc_Flags(%ecx)
363 call exec_ProcessFlags
367 testb $TF_LAUNCH,tc_Flags(%ecx)
369 movl tc_Launch(%ecx),%eax
372 ret /* HANDLE TASK FALGS!!!! */
374 Exec_Restore_Gene: movl %esp,%edi
375 movl tc_ETask(%ecx),%esi
376 movl iet_Context(%esi),%esi
385 Exec_Restore_FPU: movl %esp,%edi
386 movl tc_ETask(%ecx),%esi
387 movl iet_Context(%esi),%esi
395 Exec_Restore_SSE: movl %esp,%edi
396 movl tc_ETask(%ecx),%esi
397 movl iet_Context(%esi),%esi