|
2
|
1 ##============================================================================= |
|
|
2 ## |
|
|
3 ## context.S |
|
|
4 ## |
|
|
5 ## i386 context switch code |
|
|
6 ## |
|
|
7 ##============================================================================= |
|
|
8 #####COPYRIGHTBEGIN#### |
|
|
9 # |
|
|
10 # ------------------------------------------- |
|
|
11 # The contents of this file are subject to the Cygnus eCos Public License |
|
|
12 # Version 1.0 (the "License"); you may not use this file except in |
|
|
13 # compliance with the License. You may obtain a copy of the License at |
|
|
14 # http://sourceware.cygnus.com/ecos |
|
|
15 # |
|
|
16 # Software distributed under the License is distributed on an "AS IS" |
|
|
17 # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
|
18 # License for the specific language governing rights and limitations under |
|
|
19 # the License. |
|
|
20 # |
|
|
21 # The Original Code is eCos - Embedded Cygnus Operating System, released |
|
|
22 # September 30, 1998. |
|
|
23 # |
|
|
24 # The Initial Developer of the Original Code is Cygnus. Portions created |
|
|
25 # by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. |
|
|
26 # ------------------------------------------- |
|
|
27 # |
|
|
28 #####COPYRIGHTEND#### |
|
|
29 ##============================================================================= |
|
|
30 #######DESCRIPTIONBEGIN#### |
|
|
31 ## |
|
|
32 ## Author(s): jskov |
|
|
33 ## Contributors:jskov |
|
|
34 ## Date: 1999-01-20 |
|
|
35 ## Purpose: i386 context switch code |
|
|
36 ## Description: This file contains implementations of the thread context |
|
|
37 ## switch routines. It also contains the longjmp() and setjmp() |
|
|
38 ## routines. |
|
|
39 ## Based on PowerPC context.S, using data from SYSV ABI4, i386 |
|
|
40 ## supplement (page 37-38) |
|
|
41 ## http://www.sco.com/products/layered/develop/devspecs/abi386-4.pdf |
|
|
42 ## |
|
|
43 ######DESCRIPTIONEND#### |
|
|
44 ## |
|
|
45 ##============================================================================= |
|
|
46 |
|
|
47 #include <pkgconf/hal.h> |
|
|
48 |
|
|
49 #include "cyg/hal/i386.inc" |
|
|
50 |
|
|
51 #------------------------------------------------------------------------------ |
|
|
52 # function declaration macro |
|
|
53 |
|
|
54 #define FUNC_START(name) \ |
|
|
55 .globl name; \ |
|
|
56 name: |
|
|
57 |
|
|
58 #------------------------------------------------------------------------------ |
|
|
59 # hal_thread_switch_context |
|
|
60 # Switch thread contexts |
|
|
61 # : 0(%esp) : return address |
|
|
62 # : 4(%esp) : address of sp of next thread to execute |
|
|
63 # : 8(%esp) : address of sp save location of current thread |
|
|
64 # |
|
|
65 # %eax, %ecx, and %edx are ours to abuse. |
|
|
66 |
|
|
67 FUNC_START(hal_thread_switch_context) |
|
|
68 movl 4(%esp),%eax # next context ptr |
|
|
69 movl 8(%esp),%edx # this context ptr |
|
|
70 |
|
|
71 # Make room on the stack for the context |
|
|
72 movl %esp,%ecx # keep original SP |
|
|
73 sub $i386reg_context_size,%esp |
|
|
74 |
|
|
75 # Save next context ptr in this context. Necessary because |
|
|
76 # hal_thread_load_context expects to find the ptr on the stack, |
|
|
77 # not in a register as on PPC. |
|
|
78 movl %eax,i386reg_next_context(%esp) |
|
|
79 |
|
|
80 # Save registers |
|
|
81 movl %ecx,i386reg_esp(%esp) # original esp |
|
|
82 movl %ebp,i386reg_ebp(%esp) |
|
|
83 movl %ebx,i386reg_ebx(%esp) |
|
|
84 movl %esi,i386reg_esi(%esp) |
|
|
85 movl %edi,i386reg_edi(%esp) |
|
|
86 |
|
|
87 # Store the context ptr |
|
|
88 movl %esp,(%edx) |
|
|
89 |
|
|
90 # Now fall through to hal_thread_load_context |
|
|
91 |
|
|
92 |
|
|
93 #------------------------------------------------------------------------------ |
|
|
94 # hal_thread_load_context |
|
|
95 # Load thread context |
|
|
96 # : 4(%esp) = i386reg_next_context(%esp) = address of sp of thread to execute |
|
|
97 # Note that this function is also the second half of hal_thread_switch_context |
|
|
98 # and is simply dropped into from it. |
|
|
99 # |
|
|
100 # %eax, %ecx, and %edx are ours to abuse. |
|
|
101 |
|
|
102 FUNC_START(hal_thread_load_context) |
|
|
103 movl i386reg_next_context(%esp),%eax # get new context ptr |
|
|
104 movl (%eax),%eax |
|
|
105 |
|
|
106 # Restore registers |
|
|
107 movl i386reg_ebp(%eax),%ebp |
|
|
108 movl i386reg_ebx(%eax),%ebx |
|
|
109 movl i386reg_esi(%eax),%esi |
|
|
110 movl i386reg_edi(%eax),%edi |
|
|
111 movl i386reg_esp(%eax),%esp |
|
|
112 |
|
|
113 ret |
|
|
114 |
|
|
115 |
|
|
116 #------------------------------------------------------------------------------ |
|
|
117 # HAL longjmp, setjmp implementations |
|
|
118 # hal_setjmp saves only to callee save registers ebp, ebx, esi, edi and |
|
|
119 # and esp+pc into buffer supplied in 4(esp) |
|
|
120 # Note: These definitions are repeated in hal_arch.h. If changes are required |
|
|
121 # remember to update both sets. |
|
|
122 |
|
|
123 #define CYGARC_JMP_BUF_SP 0 |
|
|
124 #define CYGARC_JMP_BUF_EBP 1 |
|
|
125 #define CYGARC_JMP_BUF_EBX 2 |
|
|
126 #define CYGARC_JMP_BUF_ESI 3 |
|
|
127 #define CYGARC_JMP_BUF_EDI 4 |
|
|
128 #define CYGARC_JMP_BUF_PC 5 |
|
|
129 |
|
|
130 #define CYGARC_JMP_BUF_SIZE 6 |
|
|
131 |
|
|
132 FUNC_START(hal_setjmp) |
|
|
133 # Get jmpbuf pointer |
|
|
134 movl 4(%esp),%eax |
|
|
135 |
|
|
136 # Save regular registers |
|
|
137 movl %ebp,CYGARC_JMP_BUF_EBP*4(%eax) |
|
|
138 movl %ebx,CYGARC_JMP_BUF_EBX*4(%eax) |
|
|
139 movl %esi,CYGARC_JMP_BUF_ESI*4(%eax) |
|
|
140 movl %edi,CYGARC_JMP_BUF_EDI*4(%eax) |
|
|
141 |
|
|
142 # Stack and PC |
|
|
143 movl %esp,CYGARC_JMP_BUF_SP*4(%eax) |
|
|
144 movl 0(%esp),%ebx |
|
|
145 movl %ebx,CYGARC_JMP_BUF_PC*4(%eax) |
|
|
146 |
|
|
147 # Return 0 |
|
|
148 xor %eax,%eax |
|
|
149 ret |
|
|
150 |
|
|
151 |
|
|
152 # hal_longjmp loads state from 4(esp) and returns to PC stored in state |
|
|
153 |
|
|
154 FUNC_START(hal_longjmp) |
|
|
155 # Get return value |
|
|
156 movl 8(%esp),%eax |
|
|
157 |
|
|
158 # Get jmpbuf pointer |
|
|
159 movl 4(%esp),%ecx |
|
|
160 |
|
|
161 # Restore regular registers |
|
|
162 movl CYGARC_JMP_BUF_EBP*4(%ecx),%ebp |
|
|
163 movl CYGARC_JMP_BUF_EBX*4(%ecx),%ebx |
|
|
164 movl CYGARC_JMP_BUF_ESI*4(%ecx),%esi |
|
|
165 movl CYGARC_JMP_BUF_EDI*4(%ecx),%edi |
|
|
166 |
|
|
167 # Restore stack pointer |
|
|
168 movl CYGARC_JMP_BUF_SP*4(%ecx),%esp |
|
|
169 |
|
|
170 # Put return address on stack |
|
|
171 movl CYGARC_JMP_BUF_PC*4(%ecx),%edx |
|
|
172 movl %edx,0(%esp) |
|
|
173 |
|
|
174 ret |
|
|
175 |
|
|
176 #----------------------------------------------------------------------------- |
|
|
177 # End of context.S |