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