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