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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [exec/] [score/] [cpu/] [i386/] [cpu_asm.S] - Blame information for rev 389

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*  cpu_asm.s
2
 *
3
 *  This file contains all assembly code for the Intel i386 implementation
4
 *  of RTEMS.
5
 *
6
 *  COPYRIGHT (c) 1989-1999.
7
 *  On-Line Applications Research Corporation (OAR).
8
 *
9
 *  The license and distribution terms for this file may be
10
 *  found in the file LICENSE in this distribution or at
11
 *  http://www.OARcorp.com/rtems/license.html.
12
 *
13
 *  $Id: cpu_asm.S,v 1.2 2001-09-27 11:59:26 chris Exp $
14
 */
15
 
16
#include 
17
 
18
/*
19
 * Format of i386 Register structure
20
 */
21
 
22
.set REG_EFLAGS,  0
23
.set REG_ESP,     REG_EFLAGS + 4
24
.set REG_EBP,     REG_ESP + 4
25
.set REG_EBX,     REG_EBP + 4
26
.set REG_ESI,     REG_EBX + 4
27
.set REG_EDI,     REG_ESI + 4
28
.set SIZE_REGS,   REG_EDI + 4
29
 
30
        BEGIN_CODE
31
 
32
/*
33
 *  void _CPU_Context_switch( run_context, heir_context )
34
 *
35
 *  This routine performs a normal non-FP context.
36
 */
37
 
38
        .p2align  1
39
        PUBLIC (_CPU_Context_switch)
40
 
41
.set RUNCONTEXT_ARG,   4                   # save context argument
42
.set HEIRCONTEXT_ARG,  8                   # restore context argument
43
 
44
SYM (_CPU_Context_switch):
45
        movl      RUNCONTEXT_ARG(esp),eax  # eax = running threads context
46
        pushf                              # push eflags
47
        popl      REG_EFLAGS(eax)          # save eflags
48
        movl      esp,REG_ESP(eax)         # save stack pointer
49
        movl      ebp,REG_EBP(eax)         # save base pointer
50
        movl      ebx,REG_EBX(eax)         # save ebx
51
        movl      esi,REG_ESI(eax)         # save source register
52
        movl      edi,REG_EDI(eax)         # save destination register
53
 
54
        movl      HEIRCONTEXT_ARG(esp),eax # eax = heir threads context
55
 
56
restore:
57
        pushl     REG_EFLAGS(eax)          # push eflags
58
        popf                               # restore eflags
59
        movl      REG_ESP(eax),esp         # restore stack pointer
60
        movl      REG_EBP(eax),ebp         # restore base pointer
61
        movl      REG_EBX(eax),ebx         # restore ebx
62
        movl      REG_ESI(eax),esi         # restore source register
63
        movl      REG_EDI(eax),edi         # restore destination register
64
        ret
65
 
66
/*
67
 *  NOTE: May be unnecessary to reload some registers.
68
 */
69
 
70
/*
71
 *  void _CPU_Context_restore( new_context )
72
 *
73
 *  This routine performs a normal non-FP context.
74
 */
75
 
76
        PUBLIC (_CPU_Context_restore)
77
 
78
.set NEWCONTEXT_ARG,   4                   # context to restore argument
79
 
80
SYM (_CPU_Context_restore):
81
 
82
        movl      NEWCONTEXT_ARG(esp),eax  # eax = running threads context
83
        jmp       restore
84
 
85
/*PAGE
86
 *  void _CPU_Context_save_fp_context( &fp_context_ptr )
87
 *  void _CPU_Context_restore_fp_context( &fp_context_ptr )
88
 *
89
 *  This section is used to context switch an i80287, i80387,
90
 *  the built-in coprocessor or the i80486 or compatible.
91
 */
92
 
93
.set FPCONTEXT_ARG,   4                    # FP context argument
94
 
95
        .p2align  1
96
        PUBLIC (_CPU_Context_save_fp)
97
SYM (_CPU_Context_save_fp):
98
        movl      FPCONTEXT_ARG(esp),eax   # eax = &ptr to FP context area
99
        movl      (eax),eax                # eax = FP context area
100
        fsave     (eax)                    # save FP context
101
        ret
102
 
103
        .p2align  1
104
        PUBLIC (_CPU_Context_restore_fp)
105
SYM (_CPU_Context_restore_fp):
106
        movl      FPCONTEXT_ARG(esp),eax   # eax = &ptr to FP context area
107
        movl      (eax),eax                # eax = FP context area
108
        frstor    (eax)                    # restore FP context
109
        ret
110
 
111
        PUBLIC (_Exception_Handler)
112
SYM (_Exception_Handler):
113
        pusha                              # Push general purpose registers
114
        pushl   esp                        # Push exception frame address
115
        movl    _currentExcHandler, eax    # Call function storead in _currentExcHandler
116
        call    * eax
117
        addl    $4, esp
118
        popa                               # restore general purpose registers
119
        addl    $8, esp                    # skill vector number and faultCode
120
        iret
121
 
122
#define DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY(_vector) \
123
        .p2align 4                         ; \
124
        PUBLIC (rtems_exception_prologue_ ## _vector ) ; \
125
SYM (rtems_exception_prologue_ ## _vector ):             \
126
        pushl   $ _vector       ; \
127
        jmp   SYM (_Exception_Handler) ;
128
 
129
#define DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY(_vector) \
130
        .p2align 4                         ; \
131
        PUBLIC (rtems_exception_prologue_ ## _vector ) ; \
132
SYM (rtems_exception_prologue_ ## _vector ):             \
133
        pushl   $ 0             ; \
134
        pushl   $ _vector       ; \
135
        jmp   SYM (_Exception_Handler) ;
136
 
137
/*
138
 * Divide Error
139
 */
140
DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (0)
141
/*
142
 * Debug Exception
143
 */
144
DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (1)
145
/*
146
 * NMI
147
 */
148
DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (2)
149
/*
150
 * Breakpoint
151
 */
152
DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (3)
153
/*
154
 * Overflow
155
 */
156
DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (4)
157
/*
158
 * Bound Range Exceeded
159
 */
160
DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (5)
161
/*
162
 * Invalid Opcode
163
 */
164
DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (6)
165
/*
166
 * No Math Coproc
167
 */
168
DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (7)
169
/*
170
 * Double Fault
171
 */
172
DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (8)
173
/*
174
 * Coprocessor segment overrun
175
 */
176
DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (9)
177
/*
178
 * Invalid TSS
179
 */
180
DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (10)
181
/*
182
 * Segment Not Present
183
 */
184
DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (11)
185
/*
186
 * Stack segment Fault
187
 */
188
DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (12)
189
/*
190
 * General Protection Fault
191
 */
192
DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (13)
193
/*
194
 * Page Fault
195
 */
196
DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (14)
197
/*
198
 * Floating point error (NB 15 is reserved it is therefor skipped)
199
 */
200
DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (16)
201
/*
202
 * Aligment Check
203
 */
204
DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (17)
205
/*
206
 * Machine Check
207
 */
208
DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (18)
209
 
210
 
211
/*
212
 *  void *i386_Logical_to_physical(
213
 *     rtems_unsigned16  segment,
214
 *     void             *address
215
 *  );
216
 *
217
 *  Returns thirty-two bit physical address for segment:address.
218
 */
219
 
220
.set SEGMENT_ARG, 4
221
.set ADDRESS_ARG, 8
222
 
223
             PUBLIC (i386_Logical_to_physical)
224
 
225
SYM (i386_Logical_to_physical):
226
 
227
        xorl    eax,eax                # clear eax
228
        movzwl  SEGMENT_ARG(esp),ecx   # ecx = segment value
229
        movl    $ SYM (_Global_descriptor_table),edx
230
                                       # edx = address of our GDT
231
        addl    ecx,edx                # edx = address of desired entry
232
        movb    7(edx),ah              # ah = base 31:24
233
        movb    4(edx),al              # al = base 23:16
234
        shll    $16,eax                # move ax into correct bits
235
        movw    2(edx),ax              # ax = base 0:15
236
        movl    ADDRESS_ARG(esp),ecx   # ecx = address to convert
237
        addl    eax,ecx                # ecx = physical address equivalent
238
        movl    ecx,eax                # eax = ecx
239
        ret
240
 
241
/*
242
 *  void *i386_Physical_to_logical(
243
 *     rtems_unsigned16  segment,
244
 *     void             *address
245
 *  );
246
 *
247
 *  Returns thirty-two bit physical address for segment:address.
248
 */
249
 
250
/*
251
 *.set SEGMENT_ARG, 4
252
 *.set ADDRESS_ARG, 8   -- use sets from above
253
 */
254
 
255
       PUBLIC (i386_Physical_to_logical)
256
 
257
SYM (i386_Physical_to_logical):
258
        xorl    eax,eax                # clear eax
259
        movzwl  SEGMENT_ARG(esp),ecx   # ecx = segment value
260
        movl    $ SYM (_Global_descriptor_table),edx
261
                                       # edx = address of our GDT
262
        addl    ecx,edx                # edx = address of desired entry
263
        movb    7(edx),ah              # ah = base 31:24
264
        movb    4(edx),al              # al = base 23:16
265
        shll    $16,eax                # move ax into correct bits
266
        movw    2(edx),ax              # ax = base 0:15
267
        movl    ADDRESS_ARG(esp),ecx   # ecx = address to convert
268
        subl    eax,ecx                # ecx = logical address equivalent
269
        movl    ecx,eax                # eax = ecx
270
        ret
271
 
272
END_CODE
273
 
274
END

powered by: WebSVN 2.1.0

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