Added missing properties and fixed a typo.
[cake.git] / arch / i386-pc / exec / corelow.S
blob9babdbf3042c8a906bb94ca78e691f3dffd2a1aa
1 /*
2     Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3     $Id$
4 */
6 /*
7     Full low-level interrupt core. Provides AmigaOS-like preemptive
8     multitasking.
9 */
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
15     be preserved.
18 #include "aros/i386/asm.h"
19 #include <asm/segments.h>
21 #define SAVE_REGS       \
22     pushl   %eax;       \
23     pushl   %ecx;       \
24     pushl   %edx;       \
25     push    %ds;        \
26     push    %es;        \
27     movl    $KERNEL_DS,%edx; \
28     mov     %dx,%ds;    \
29     mov     %dx,%es
31 #define RESTORE_REGS    \
32     pop     %es;        \
33     pop     %ds;        \
34     popl    %edx;       \
35     popl    %ecx;       \
36     popl    %eax
38 #define R_es        0x00
39 #define R_ds        0x04
40 #define R_edx       0x08
41 #define R_ecx       0x0c
42 #define R_eax       0x10
43 #define R_param     0x14
46     Save/restore all registers. These macros are used mostly inside Switch
47     procedure.
50 #define SAVE_ALL        \
51     push    %es;        \
52     push    %ds;        \
53     pushl   %eax;       \
54     pushl   %ebp;       \
55     pushl   %edi;       \
56     pushl   %esi;       \
57     pushl   %edx;       \
58     pushl   %ecx;       \
59     pushl   %ebx;       \
60     movl    $KERNEL_DS,%edx; \
61     mov     %dx,%ds;    \
62     mov     %dx,%es
64 #define RESTORE_ALL     \
65     popl    %ebx;       \
66     popl    %ecx;       \
67     popl    %edx;       \
68     popl    %esi;       \
69     popl    %edi;       \
70     popl    %ebp;       \
71     popl    %eax;       \
72     pop     %ds;        \
73     pop     %es
75                     .text
77                     .balign 32,0x90
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 */
86                     .balign 32,0x90
87                     .globl  sys_Supervisor
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 */
95                     .balign 32,0x90
96                     .globl  exec_SuperState
97                     .type   exec_SuperState,@function
98 exec_SuperState:
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 */
107 exec_SS_IRET:
108         iret
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
115     as follows:
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.
127                     .text
128                     .balign 32,0x90
129                     .globl  Exec_SystemCall
130                     .type   Exec_SystemCall,@function
132 Exec_SystemCall:    negl    %eax
133                     pushl   %eax
134                     SAVE_REGS
135                     cmpl    $4,%eax
136                     jae     restore_all
137                     call    *sys_call_table(,%eax,4)
138                     movl    %eax,R_eax(%esp)
139                     jmp     Exec_ExitIntr
140 restore_all:        RESTORE_REGS
141                     addl    $4,%esp
142                     iret
144                     .balign 32,0x90
145                     .globl  Exec_ExitIntr
146                     .type   Exec_ExitIntr,@function
148 Exec_ExitIntr:      cmpw    $KERNEL_DS,R_ds(%esp)
149                     je      restore_all
150                     cli
151                     movl    4,%eax
152                     testw   $0x20,SysFlags(%eax)        /* SFF_SoftInt set? */
153                     je      Exec_ExitIntr_NoSoftInts
155                     pushl   %eax
156                     call    sys_Cause
157                     popl    %eax
158                                     
159 Exec_ExitIntr_NoSoftInts:
160                     cmpb    $0,TDNestCnt(%eax)
161                     jge     restore_all
162                     testw   $0x80,AttnResched(%eax)
163                     je      restore_all
164                     jmp     Exec_Schedule_x
166                     .balign 32,0x90
167                     .globl  Exec_Schedule
168                     .type   Exec_Schedule,@function
170 Exec_Schedule:      pushl   $0
171                     SAVE_REGS
172 Exec_Schedule_x:    cli                                     /* stegerg: added -> CHECKME */
173                     movl    4,%edx
174                     andw    $0xff7f,AttnResched(%edx)
175                     movl    ThisTask(%edx),%eax
176                     testb   $TF_EXCEPT,tc_Flags(%eax)
177                     jne     1f
179                     lea     TaskReady(%edx),%ecx
180                     cmpl    lh_TailPred(%ecx),%ecx
181                     je      restore_all
183                     movl    lh_Head(%ecx),%ecx
184                     movb    ln_Pri(%ecx),%cl
185                     cmpb    ln_Pri(%eax),%cl
186                     jge     1f
188 #warning TODO: Implement tasks Time Slices
190                     testw   $0x2000,SysFlags(%edx)
191                     je      restore_all
193 1:                  pushl   %edx
194                     pushl   %eax
195                     movb    $TS_READY,tc_State(%eax)
196                     lea     TaskReady(%edx),%ecx
197                     pushl   %ecx
198                     call    *Enqueue(%edx)
199                     popl    %eax
200                     popl    %eax
201                     popl    %edx
203                     movl    Switch(%edx),%eax
204                     movl    %eax,R_param(%esp)
205                     RESTORE_REGS
206                     ret
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.
215                     .balign 32,0x90
216                     .globl  Exec_Switch
217                     .type   Exec_Switch,@function
218 Exec_Switch:        cli                         /* Disable all interrupts */
219                     cld
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
228                     movl    $14,%ecx
229                     rep
230                     movsl
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)
246                     je      Exec_Dispatch_x
248                     movl    tc_Switch(%ebx),%eax
249                     call    *%eax
250                     jmp     Exec_Dispatch_x
252                     .balign 32,0x90
253                     .globl  Exec_Switch_FPU
254                     .type   Exec_Switch_FPU,@function
255 Exec_Switch_FPU:    cli
256                     cld
257                     SAVE_ALL
258                     movl    4,%eax
259                     movl    ThisTask(%eax),%eax
261                     movl    %esp,%esi
262                     movl    tc_ETask(%eax),%edi
263                     movl    iet_Context(%edi),%edi
264                     
265                     movl    $14,%ecx
266                     rep
267                     movsl
268                     
269                     fsave   (%edi)
271                     movl    $Exec_Restore_FPU,%edi
272                     jmp     Exec_Switch_Common
274                     .balign 32,0x90
275                     .globl  Exec_Switch_SSE
276                     .type   Exec_Switch_SSE,@function
277 Exec_Switch_SSE:    cli
278                     cld
279                     SAVE_ALL
280                     movl    4,%eax
281                     movl    ThisTask(%eax),%eax
283                     movl    %esp,%esi
284                     movl    tc_ETask(%eax),%edi
285                     movl    iet_Context(%edi),%edi
286                     movl    $14,%ecx
287                     rep
288                     movsl
290                     addl    $15,%edi
291                     andl    $~15,%edi
292                     fxsave  (%edi)
294                     movl    $Exec_Restore_SSE,%edi
295                     jmp     Exec_Switch_Common
297                     .balign 32,0x90
298                     .globl  Exec_Dispatch_SSE
299                     .type   Exec_Dispatch_SSE,@function
300                     
301 Exec_Dispatch_SSE:  SAVE_ALL
302                     movl    $Exec_Restore_SSE,%edi
303                     jmp     Exec_Dispatch_com
305                     .balign 32,0x90
306                     .globl  Exec_Dispatch_FPU
307                     .type   Exec_Dispatch_FPU,@function
308                     
309 Exec_Dispatch_FPU:  SAVE_ALL
310                     movl    $Exec_Restore_FPU,%edi
311                     jmp     Exec_Dispatch_com
312                     
313                     .balign 32,0x90
314                     .globl  Exec_Dispatch
315                     .type   Exec_Dispatch,@function
316                     
317 Exec_Dispatch:      SAVE_ALL
318                     movl    $Exec_Restore_Gene,%edi
319 Exec_Dispatch_com:  movl    4,%ebp
320                     movb    $-1,IDNestCnt(%ebp)
321 /*                    sti*/
323 Exec_Dispatch_x:    cli
324                     leal    TaskReady(%ebp),%eax
325                     movl    lh_Head(%eax),%ecx
326                     movl    ln_Succ(%ecx),%edx
327                     andl    %edx,%edx
328                     jne     1f
330                     incl    IdleCount(%ebp)
331                     orw     $0x80,AttnResched(%ebp)
332                     sti
333                     hlt
334                     
335                     cli
336                     testw   $0x20,SysFlags(%ebp) /* SFF_SoftInt set? */
337                     je      Exec_Dispatch_x
338                     
339                     call    sys_Cause
340                     
341                     jmp     Exec_Dispatch_x
343 1:                  movl    %edx,lh_Head(%eax)
344                     movl    %eax,ln_Pred(%edx)
345                     incl    DispCount(%ebp)
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)
358                     jge     1f
359                     /* sti */
361                     testb   $TF_EXCEPT | TF_LAUNCH,tc_Flags(%ecx)
362                     je      1f
363                     call    exec_ProcessFlags
364 1:                  jmp     *%edi
366 exec_ProcessFlags:
367                     testb   $TF_LAUNCH,tc_Flags(%ecx)
368                     je      1f
369                     movl    tc_Launch(%ecx),%eax
370                     call    *%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
377                     movl    $14,%ecx
378                     cld
379                     rep
380                     movsl
382                     RESTORE_ALL
383                     iret
385 Exec_Restore_FPU:   movl    %esp,%edi
386                     movl    tc_ETask(%ecx),%esi
387                     movl    iet_Context(%esi),%esi
388                     movl    $14,%ecx
389                     rep
390                     movsl
391                     frstor  (%esi)
392                     RESTORE_ALL
393                     iret
395 Exec_Restore_SSE:   movl    %esp,%edi
396                     movl    tc_ETask(%ecx),%esi
397                     movl    iet_Context(%esi),%esi
398                     movl    $14,%ecx
399                     rep
400                     movsl
401                     addl    $15,%esi
402                     andl    $~15,%esi
403                     fxrstor (%esi)
404                     RESTORE_ALL
405                     iret