001 /* Copyright (C) 2000-2004, The KOS team
002 Copyright (C) 1999 Free Software Foundation, Inc.
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 .file "cpu_context_switch.S"
022
023 .text
024
025
026 .globl sos_cpu_kstate_switch
027 .type sos_cpu_kstate_switch, @function
028 sos_cpu_kstate_switch:
029 // arg2= to_context -- esp+64
030 // arg1= from_context -- esp+60
031 // caller ip -- esp+56
032 pushf // (eflags) esp+52
033 pushl %cs // (cs) esp+48
034 pushl $resume_pc // (ip) esp+44
035 pushl $0 // (error code) esp+40
036 pushl %ebp // esp+36
037 pushl %edi // esp+32
038 pushl %esi // esp+28
039 pushl %edx // esp+24
040 pushl %ecx // esp+20
041 pushl %ebx // esp+16
042 pushl %eax // esp+12
043 subl $2, %esp // (alignment) esp+10
044 pushw %ss // esp+8
045 pushw %ds // esp+6
046 pushw %es // esp+4
047 pushw %fs // esp+2
048 pushw %gs // esp
049
050 /*
051 * Now that the original eax/ebx are store, we can use them safely
052 */
053
054 /* Store the address of the saved context */
055 movl 60(%esp), %ebx
056 movl %esp, (%ebx)
057
058 /* This is the proper context switch ! We change the stack here */
059 movl 64(%esp), %esp
060
061 /* Restore the CPU context */
062 popw %gs
063 popw %fs
064 popw %es
065 popw %ds
066 popw %ss
067 addl $2,%esp
068 popl %eax
069 popl %ebx
070 popl %ecx
071 popl %edx
072 popl %esi
073 popl %edi
074 popl %ebp
075 addl $4, %esp /* Ignore "error code" */
076
077 /* This restores the eflags, the cs and the eip registers */
078 iret /* equivalent to: popfl ; ret */
079
080 resume_pc:
081 // Same context as that when sos_cpu_kstate_switch got called
082 // arg2= to_context -- esp+8
083 // arg1= from_context -- esp+4
084 // caller ip -- esp
085 ret
086
087
088
089 /* ------------------------- */
090 .globl sos_cpu_kstate_exit_to
091 .type sos_cpu_kstate_exit_to, @function
092 sos_cpu_kstate_exit_to:
093 // arg3= reclaiming_arg -- esp+12
094 // arg2= reclaiming_func -- esp+8
095 // arg1= to_context -- esp+4
096 // caller ip -- esp
097
098 /* Store the current SP in a temporary register */
099 movl %esp, %eax
100
101 /* This is the proper context switch ! We change the stack here */
102 movl 4(%eax), %esp
103
104 /* Call the reclaiming function (remember: the old frame address
105 is stored in eax) */
106 pushl 12(%eax)
107 call *8(%eax)
108 addl $4, %esp
109
110 /* Restore the CPU context */
111 popw %gs
112 popw %fs
113 popw %es
114 popw %ds
115 popw %ss
116 addl $2,%esp
117 popl %eax
118 popl %ebx
119 popl %ecx
120 popl %edx
121 popl %esi
122 popl %edi
123 popl %ebp
124 addl $4, %esp /* Ignore "error code" */
125
126 /* This restores the eflags, the cs and the eip registers */
127 iret /* equivalent to: popfl ; ret */
128