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
021 024
022 .file "cpu_context_switch.S" 025 .file "cpu_context_switch.S"
023 026
024 .text 027 .text
025 028
>> 029
>> 030 /**
>> 031 * C Function called by the routines below in order to tell the CPU
>> 032 * where will be the kernel stack (needed by the interrupt handlers)
>> 033 * when next_ctxt will come back into kernel mode.
>> 034 *
>> 035 * void sos_cpu_context_update_kernel_tss(struct sos_cpu_state *next_ctxt)
>> 036 *
>> 037 * @see end of cpu_context.c
>> 038 */
>> 039 .extern sos_cpu_context_update_kernel_tss
>> 040
026 041
027 .globl sos_cpu_context_switch 042 .globl sos_cpu_context_switch
028 .type sos_cpu_context_switch, @function 043 .type sos_cpu_context_switch, @function
029 sos_cpu_context_switch: 044 sos_cpu_context_switch:
030 // arg2= to_context -- esp+64 045 // arg2= to_context -- esp+64
031 // arg1= from_context -- esp+60 046 // arg1= from_context -- esp+60
032 // caller ip -- esp+56 047 // caller ip -- esp+56
033 pushf // (eflags) esp+52 048 pushf // (eflags) esp+52
034 pushl %cs // (cs) esp+48 049 pushl %cs // (cs) esp+48
035 pushl $resume_pc // (ip) esp+44 050 pushl $resume_pc // (ip) esp+44
036 pushl $0 // (error code) esp+40 051 pushl $0 // (error code) esp+40
037 pushl %ebp // esp+36 052 pushl %ebp // esp+36
038 pushl %edi // esp+32 053 pushl %edi // esp+32
039 pushl %esi // esp+28 054 pushl %esi // esp+28
040 pushl %edx // esp+24 055 pushl %edx // esp+24
041 pushl %ecx // esp+20 056 pushl %ecx // esp+20
042 pushl %ebx // esp+16 057 pushl %ebx // esp+16
043 pushl %eax // esp+12 058 pushl %eax // esp+12
044 subl $2, %esp // (alignment) esp+10 059 subl $2, %esp // (alignment) esp+10
045 pushw %ss // esp+8 060 pushw %ss // esp+8
046 pushw %ds // esp+6 061 pushw %ds // esp+6
047 pushw %es // esp+4 062 pushw %es // esp+4
048 pushw %fs // esp+2 063 pushw %fs // esp+2
049 pushw %gs // esp 064 pushw %gs // esp
050 065
051 /* 066 /*
052 * Now that the original eax/ebx are stored, 067 * Now that the original eax/ebx are stored, we can use them safely
053 */ 068 */
054 069
055 /* Store the address of the saved context */ 070 /* Store the address of the saved context */
056 movl 60(%esp), %ebx 071 movl 60(%esp), %ebx
057 movl %esp, (%ebx) 072 movl %esp, (%ebx)
058 073
059 /* This is the proper context switch ! We ch 074 /* This is the proper context switch ! We change the stack here */
060 movl 64(%esp), %esp 075 movl 64(%esp), %esp
061 076
>> 077 /* Prepare kernel TSS in case we are switching to a user thread: we
>> 078 make sure that we will come back into the kernel at a correct
>> 079 stack location */
>> 080 pushl %esp /* Pass the location of the context we are
>> 081 restoring to the function */
>> 082 call sos_cpu_context_update_kernel_tss
>> 083 addl $4, %esp
>> 084
062 /* Restore the CPU context */ 085 /* Restore the CPU context */
063 popw %gs 086 popw %gs
064 popw %fs 087 popw %fs
065 popw %es 088 popw %es
066 popw %ds 089 popw %ds
067 popw %ss 090 popw %ss
068 addl $2,%esp 091 addl $2,%esp
069 popl %eax 092 popl %eax
070 popl %ebx 093 popl %ebx
071 popl %ecx 094 popl %ecx
072 popl %edx 095 popl %edx
073 popl %esi 096 popl %esi
074 popl %edi 097 popl %edi
075 popl %ebp 098 popl %ebp
076 addl $4, %esp /* Ignore "error code" */ 099 addl $4, %esp /* Ignore "error code" */
077 100
078 /* This restores the eflags, the cs and the 101 /* This restores the eflags, the cs and the eip registers */
079 iret /* equivalent to: popfl ; ret */ 102 iret /* equivalent to: popfl ; ret */
080 103
081 resume_pc: 104 resume_pc:
082 // Same context as that when sos_cpu_c 105 // Same context as that when sos_cpu_context_switch got called
083 // arg2= to_context -- esp+8 106 // arg2= to_context -- esp+8
084 // arg1= from_context -- esp+4 107 // arg1= from_context -- esp+4
085 // caller ip -- esp 108 // caller ip -- esp
086 ret 109 ret
087 110
088 111
089 112
090 /* ------------------------- */ 113 /* ------------------------- */
091 .globl sos_cpu_context_exit_to 114 .globl sos_cpu_context_exit_to
092 .type sos_cpu_context_exit_to, @function 115 .type sos_cpu_context_exit_to, @function
093 sos_cpu_context_exit_to: 116 sos_cpu_context_exit_to:
094 // arg3= reclaiming_arg -- esp+12 117 // arg3= reclaiming_arg -- esp+12
095 // arg2= reclaiming_func -- esp+8 118 // arg2= reclaiming_func -- esp+8
096 // arg1= to_context -- esp+4 119 // arg1= to_context -- esp+4
097 // caller ip -- esp 120 // caller ip -- esp
098 121
099 /* Store the current SP in a temporary regis 122 /* Store the current SP in a temporary register */
100 movl %esp, %eax 123 movl %esp, %eax
101 124
102 /* This is the proper context switch ! We ch 125 /* This is the proper context switch ! We change the stack here */
103 movl 4(%eax), %esp 126 movl 4(%eax), %esp
104 127
105 /* Call the reclaiming function (remember: t 128 /* Call the reclaiming function (remember: the old frame address
106 is stored in eax) */ 129 is stored in eax) */
107 pushl 12(%eax) 130 pushl 12(%eax)
108 call *8(%eax) 131 call *8(%eax)
109 addl $4, %esp 132 addl $4, %esp
>> 133
>> 134 /* Prepare kernel TSS in case we are switching to a user thread: we
>> 135 make sure that we will come back into the kernel at a correct
>> 136 stack location */
>> 137 pushl %esp /* Pass the location of the context we are
>> 138 restoring to the function */
>> 139 call sos_cpu_context_update_kernel_tss
>> 140 addl $4, %esp
110 141
111 /* Restore the CPU context */ 142 /* Restore the CPU context */
112 popw %gs 143 popw %gs
113 popw %fs 144 popw %fs
114 popw %es 145 popw %es
115 popw %ds 146 popw %ds
116 popw %ss 147 popw %ss
117 addl $2,%esp 148 addl $2,%esp
118 popl %eax 149 popl %eax
119 popl %ebx 150 popl %ebx
120 popl %ecx 151 popl %ecx
121 popl %edx 152 popl %edx
122 popl %esi 153 popl %esi
123 popl %edi 154 popl %edi
124 popl %ebp 155 popl %ebp
125 addl $4, %esp /* Ignore "error code" */ 156 addl $4, %esp /* Ignore "error code" */
126 157
127 /* This restores the eflags, the cs and the 158 /* This restores the eflags, the cs and the eip registers */
128 iret /* equivalent to: popfl ; ret */ 159 iret /* equivalent to: popfl ; ret */