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