OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [synth/] [i386linux/] [current/] [src/] [context.S] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
##=============================================================================
2
##
3
##      context.S
4
##
5
##      x86 thread context manipulation.
6
##
7
##=============================================================================
8
## ####ECOSGPLCOPYRIGHTBEGIN####
9
## -------------------------------------------
10
## This file is part of eCos, the Embedded Configurable Operating System.
11
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
12
##
13
## eCos is free software; you can redistribute it and/or modify it under
14
## the terms of the GNU General Public License as published by the Free
15
## Software Foundation; either version 2 or (at your option) any later
16
## version.
17
##
18
## eCos is distributed in the hope that it will be useful, but WITHOUT
19
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21
## for more details.
22
##
23
## You should have received a copy of the GNU General Public License
24
## along with eCos; if not, write to the Free Software Foundation, Inc.,
25
## 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26
##
27
## As a special exception, if other files instantiate templates or use
28
## macros or inline functions from this file, or you compile this file
29
## and link it with other works to produce a work based on this file,
30
## this file does not by itself cause the resulting work to be covered by
31
## the GNU General Public License. However the source code for this file
32
## must still be made available in accordance with section (3) of the GNU
33
## General Public License v2.
34
##
35
## This exception does not invalidate any other reasons why a work based
36
## on this file might be covered by the GNU General Public License.
37
## -------------------------------------------
38
## ####ECOSGPLCOPYRIGHTEND####
39
##=============================================================================
40
#######DESCRIPTIONBEGIN####
41
##
42
## Author(s):   jskov
43
## Contributors:jskov, pjo, nickg, bartv
44
## Date:        1999-03-11
45
## Purpose:     CPU-specific code
46
## Description: This file contains the code needed to manage the
47
##              CPU on an i386/Linux synthetic target.
48
##
49
######DESCRIPTIONEND####
50
##
51
##=============================================================================
52
 
53
#include 
54
 
55
#------------------------------------------------------------------------------
56
# function declaration macro
57
 
58
#define FUNC_START(name)                        \
59
        .globl name;                            \
60
name:
61
 
62
#------------------------------------------------------------------------------
63
# Context switch and setjmp/longjmp support.
64
# Based on PowerPC context.S, using data from SYSV ABI4, i386
65
# supplement (page 37-38)
66
# http://www.sco.com/products/layered/develop/devspecs/abi386-4.pdf
67
#
68
# There is no need to worry about saving floating point context. If
69
# a switch occurs because of an interrupt/signal, the system will have
70
# saved the fpu state already before the signal handler was invoked,
71
# and the state will be returned when the signal handler returns i.e.
72
# when the interrupted thread is reactivated. If a context switch is
73
# voluntary, for example a call to cyg_thread_yield(), then according
74
# to the calling conventions all fpu registers are CALL_USED_REGISTERS
75
# (gcc/config/i386/i386.h) and will have been saved by the calling
76
# code.
77
#
78
# FIXME: it may be appropriate to match eCos thread contexts
79
# more closely onto Linux sigcontexts - that might facilitate
80
# thread-aware debugging.
81
 
82
# hal_thread_switch_context
83
# Switch thread contexts
84
# :     0(%esp) :     return address
85
# :     4(%esp) :     address of sp of next thread to execute
86
# :     8(%esp) :     address of sp save location of current thread
87
#
88
# %eax, %ecx, and %edx are ours to abuse.
89
 
90
        .extern hal_interrupts_enabled
91
        .extern hal_enable_interrupts
92
 
93
FUNC_START(hal_thread_switch_context)
94
        movl    4(%esp),%eax            # next context ptr
95
        movl    8(%esp),%edx            # this context ptr
96
 
97
        # Make room on the stack for the context
98
        movl    %esp,%ecx               # keep original SP
99
        sub     $i386reg_context_size,%esp
100
 
101
        # Save next context ptr in this context. Necessary because
102
        # hal_thread_load_context expects to find the ptr on the stack,
103
        # not in a register as on PPC.
104
        movl    %eax,i386reg_next_context(%esp)
105
 
106
        # Save registers
107
        movl    %ecx,i386reg_esp(%esp)  # original esp
108
        movl    %ebp,i386reg_ebp(%esp)
109
        movl    %ebx,i386reg_ebx(%esp)
110
        movl    %esi,i386reg_esi(%esp)
111
        movl    %edi,i386reg_edi(%esp)
112
 
113
        # And interrupt state
114
        movl    hal_interrupts_enabled,%eax
115
        movl    %eax,i386reg_interrupts(%esp)
116
 
117
        # Store the context ptr
118
        movl    %esp,(%edx)
119
 
120
        # Now fall through to hal_thread_load_context
121
 
122
 
123
#------------------------------------------------------------------------------
124
# hal_thread_load_context
125
# Load thread context
126
# : 4(%esp) = i386reg_next_context(%esp) = address of sp of thread to execute
127
# Note that this function is also the second half of hal_thread_switch_context
128
# and is simply dropped into from it.
129
#
130
# %eax, %ecx, and %edx are ours to abuse.
131
 
132
FUNC_START(hal_thread_load_context)
133
 
134
        movl    i386reg_next_context(%esp),%eax # get new context ptr
135
        movl    (%eax),%eax
136
 
137
        # Restore registers
138
        movl    i386reg_ebp(%eax),%ebp
139
        movl    i386reg_ebx(%eax),%ebx
140
        movl    i386reg_esi(%eax),%esi
141
        movl    i386reg_edi(%eax),%edi
142
        movl    i386reg_esp(%eax),%esp
143
 
144
        # And see what needs to happen about interrupts
145
        movl    i386reg_interrupts(%eax),%eax
146
        cmpl    hal_interrupts_enabled,%eax
147
        je      interrupts_ok
148
 
149
        # The saved interrupt state differs from the current one.
150
        # If interrupts are supposed to be enabled then invoke
151
        # hal_enable_interrupts. That can be done as a tail call.
152
        # If interrupts are supposed to be disabled then just
153
        # update the global variable.
154
        cmpl    $0,%eax
155
        jne     hal_enable_interrupts
156
        movl    %eax,hal_interrupts_enabled
157
 
158
interrupts_ok:
159
        ret
160
 
161
 
162
#------------------------------------------------------------------------------
163
# HAL longjmp, setjmp implementations
164
# hal_setjmp saves only to callee save registers ebp, ebx, esi, edi and
165
# and esp+pc into buffer supplied in 4(esp)
166
# Note: These definitions are repeated in hal_arch.h. If changes are required
167
# remember to update both sets.
168
 
169
#define CYGARC_JMP_BUF_SP        0
170
#define CYGARC_JMP_BUF_EBP       1
171
#define CYGARC_JMP_BUF_EBX       2
172
#define CYGARC_JMP_BUF_ESI       3
173
#define CYGARC_JMP_BUF_EDI       4
174
#define CYGARC_JMP_BUF_PC        5
175
 
176
#define CYGARC_JMP_BUF_SIZE      6
177
 
178
FUNC_START(hal_setjmp)
179
        # Get jmpbuf pointer
180
        movl    4(%esp),%eax
181
 
182
        # Save regular registers
183
        movl    %ebp,CYGARC_JMP_BUF_EBP*4(%eax)
184
        movl    %ebx,CYGARC_JMP_BUF_EBX*4(%eax)
185
        movl    %esi,CYGARC_JMP_BUF_ESI*4(%eax)
186
        movl    %edi,CYGARC_JMP_BUF_EDI*4(%eax)
187
 
188
        # Stack and PC
189
        movl    %esp,CYGARC_JMP_BUF_SP*4(%eax)
190
        movl    0(%esp),%edx
191
        movl    %edx,CYGARC_JMP_BUF_PC*4(%eax)
192
 
193
        # Return 0
194
        xor     %eax,%eax
195
        ret
196
 
197
 
198
# hal_longjmp loads state from 4(esp) and returns to PC stored in state
199
 
200
FUNC_START(hal_longjmp)
201
        # Get return value
202
        movl    8(%esp),%eax
203
 
204
        # Get jmpbuf pointer
205
        movl    4(%esp),%ecx
206
 
207
        # Restore regular registers
208
        movl    CYGARC_JMP_BUF_EBP*4(%ecx),%ebp
209
        movl    CYGARC_JMP_BUF_EBX*4(%ecx),%ebx
210
        movl    CYGARC_JMP_BUF_ESI*4(%ecx),%esi
211
        movl    CYGARC_JMP_BUF_EDI*4(%ecx),%edi
212
 
213
        # Restore stack pointer
214
        movl    CYGARC_JMP_BUF_SP*4(%ecx),%esp
215
 
216
        # Put return address on stack
217
        movl    CYGARC_JMP_BUF_PC*4(%ecx),%edx
218
        movl    %edx,0(%esp)
219
 
220
        ret
221
 
222
#------------------------------------------------------------------------------
223
# end of linux.S

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.