source: rtems/cpukit/score/cpu/i386/cpu_asm.S @ 270e3cc

4.104.114.84.95
Last change on this file since 270e3cc was 08311cc3, checked in by Joel Sherrill <joel.sherrill@…>, on 11/17/99 at 17:51:34

Updated copyright notice.

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/*  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$
14 */
15
16#include <asm.h>
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
44SYM (_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
56restore:
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
80SYM (_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)
97SYM (_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)
105SYM (_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)
112SYM (_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 ) ; \
125SYM (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 ) ; \
132SYM (rtems_exception_prologue_ ## _vector ):             \
133        pushl   $ 0             ; \
134        pushl   $ _vector       ; \
135        jmp   SYM (_Exception_Handler) ;
136
137/*
138 * Divide Error
139 */     
140DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (0)
141/*
142 * Debug Exception
143 */     
144DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (1)
145/*
146 * NMI
147 */     
148DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (2)
149/*
150 * Breakpoint
151 */     
152DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (3)
153/*
154 * Overflow
155 */     
156DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (4)
157/*
158 * Bound Range Exceeded
159 */     
160DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (5)
161/*
162 * Invalid Opcode
163 */     
164DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (6)
165/*
166 * No Math Coproc
167 */     
168DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (7)
169/*
170 * Double Fault
171 */     
172DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (8)
173/*
174 * Coprocessor segment overrun
175 */     
176DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (9)
177/*
178 * Invalid TSS
179 */     
180DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (10)
181/*
182 * Segment Not Present
183 */     
184DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (11)
185/*
186 * Stack segment Fault
187 */     
188DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (12)
189/*
190 * General Protection Fault
191 */     
192DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (13)
193/*
194 * Page Fault
195 */     
196DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (14)
197/*
198 * Floating point error (NB 15 is reserved it is therefor skipped)
199 */     
200DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (16)
201/*
202 * Aligment Check
203 */     
204DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (17)
205/*
206 * Machine Check
207 */     
208DISTINCT_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
225SYM (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
257SYM (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
272END_CODE
273
274END
Note: See TracBrowser for help on using the repository browser.