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