001 /* Copyright (C) 2005 David Decotigny
002 Copyright (C) 2000-2004, The KOS team
003
004 This program is free software; you can redistribute it and/or
005 modify it under the terms of the GNU General Public License
006 as published by the Free Software Foundation; either version 2
007 of the License, or (at your option) any later version.
008
009 This program is distributed in the hope that it will be useful,
010 but WITHOUT ANY WARRANTY; without even the implied warranty of
011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012 GNU General Public License for more details.
013
014 You should have received a copy of the GNU General Public License
015 along with this program; if not, write to the Free Software
016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
017 USA.
018 */
019 #define ASM_SOURCE 1
020
021
022 .file "cpu_context_switch.S"
023
024 .text
025
026
027 .globl sos_cpu_context_switch
028 .type sos_cpu_context_switch, @function
029 sos_cpu_context_switch:
030 // arg2= to_context -- esp+64
031 // arg1= from_context -- esp+60
032 // caller ip -- esp+56
033 pushf // (eflags) esp+52
034 pushl %cs // (cs) esp+48
035 pushl $resume_pc // (ip) esp+44
036 pushl $0 // (error code) esp+40
037 pushl %ebp // esp+36
038 pushl %edi // esp+32
039 pushl %esi // esp+28
040 pushl %edx // esp+24
041 pushl %ecx // esp+20
042 pushl %ebx // esp+16
043 pushl %eax // esp+12
044 subl $2, %esp // (alignment) esp+10
045 pushw %ss // esp+8
046 pushw %ds // esp+6
047 pushw %es // esp+4
048 pushw %fs // esp+2
049 pushw %gs // esp
050
051 /*
052 * Now that the original eax/ebx are stored, we can use them safely
053 */
054
055 /* Store the address of the saved context */
056 movl 60(%esp), %ebx
057 movl %esp, (%ebx)
058
059 /* This is the proper context switch ! We change the stack here */
060 movl 64(%esp), %esp
061
062 /* Restore the CPU context */
063 popw %gs
064 popw %fs
065 popw %es
066 popw %ds
067 popw %ss
068 addl $2,%esp
069 popl %eax
070 popl %ebx
071 popl %ecx
072 popl %edx
073 popl %esi
074 popl %edi
075 popl %ebp
076 addl $4, %esp /* Ignore "error code" */
077
078 /* This restores the eflags, the cs and the eip registers */
079 iret /* equivalent to: popfl ; ret */
080
081 resume_pc:
082 // Same context as that when sos_cpu_context_switch got called
083 // arg2= to_context -- esp+8
084 // arg1= from_context -- esp+4
085 // caller ip -- esp
086 ret
087
088
089
090 /* ------------------------- */
091 .globl sos_cpu_context_exit_to
092 .type sos_cpu_context_exit_to, @function
093 sos_cpu_context_exit_to:
094 // arg3= reclaiming_arg -- esp+12
095 // arg2= reclaiming_func -- esp+8
096 // arg1= to_context -- esp+4
097 // caller ip -- esp
098
099 /* Store the current SP in a temporary register */
100 movl %esp, %eax
101
102 /* This is the proper context switch ! We change the stack here */
103 movl 4(%eax), %esp
104
105 /* Call the reclaiming function (remember: the old frame address
106 is stored in eax) */
107 pushl 12(%eax)
108 call *8(%eax)
109 addl $4, %esp
110
111 /* Restore the CPU context */
112 popw %gs
113 popw %fs
114 popw %es
115 popw %ds
116 popw %ss
117 addl $2,%esp
118 popl %eax
119 popl %ebx
120 popl %ecx
121 popl %edx
122 popl %esi
123 popl %edi
124 popl %ebp
125 addl $4, %esp /* Ignore "error code" */
126
127 /* This restores the eflags, the cs and the eip registers */
128 iret /* equivalent to: popfl ; ret */