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