source: rtems/c/src/exec/score/cpu/i386/cpu_asm.s @ eb562f2

4.104.114.84.95
Last change on this file since eb562f2 was eb562f2, checked in by Joel Sherrill <joel.sherrill@…>, on 08/21/98 at 16:39:52

Patch from Eric Valette <valette@…>:

Here is a patch that enables to catch exception
and get message before crashing RTEMS :)

It should be generic to any Intel port although enabled
only for pc386 BSP...

[Joel] I fixed the bug I introduced in irq_asm.s...

  • Property mode set to 100644
File size: 7.8 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-1998.
7 *  On-Line Applications Research Corporation (OAR).
8 *  Copyright assigned to U.S. Government, 1994.
9 *
10 *  The license and distribution terms for this file may be
11 *  found in the file LICENSE in this distribution or at
12 *  http://www.OARcorp.com/rtems/license.html.
13 *
14 *  $Id$
15 */
16
17#include <asm.h>
18
19/*
20 * Format of i386 Register structure
21 */
22
23.set REG_EFLAGS,  0
24.set REG_ESP,     REG_EFLAGS + 4
25.set REG_EBP,     REG_ESP + 4
26.set REG_EBX,     REG_EBP + 4
27.set REG_ESI,     REG_EBX + 4
28.set REG_EDI,     REG_ESI + 4
29.set SIZE_REGS,   REG_EDI + 4
30
31        BEGIN_CODE
32
33/*
34 *  void _CPU_Context_switch( run_context, heir_context )
35 *
36 *  This routine performs a normal non-FP context.
37 */
38
39        .p2align  1
40        PUBLIC (_CPU_Context_switch)
41
42.set RUNCONTEXT_ARG,   4                   # save context argument
43.set HEIRCONTEXT_ARG,  8                   # restore context argument
44
45SYM (_CPU_Context_switch):
46        movl      RUNCONTEXT_ARG(esp),eax  # eax = running threads context
47        pushf                              # push eflags
48        popl      REG_EFLAGS(eax)          # save eflags
49        movl      esp,REG_ESP(eax)         # save stack pointer
50        movl      ebp,REG_EBP(eax)         # save base pointer
51        movl      ebx,REG_EBX(eax)         # save ebx
52        movl      esi,REG_ESI(eax)         # save source register
53        movl      edi,REG_EDI(eax)         # save destination register
54
55        movl      HEIRCONTEXT_ARG(esp),eax # eax = heir threads context
56
57restore:
58        pushl     REG_EFLAGS(eax)          # push eflags
59        popf                               # restore eflags
60        movl      REG_ESP(eax),esp         # restore stack pointer
61        movl      REG_EBP(eax),ebp         # restore base pointer
62        movl      REG_EBX(eax),ebx         # restore ebx
63        movl      REG_ESI(eax),esi         # restore source register
64        movl      REG_EDI(eax),edi         # restore destination register
65        ret
66
67/*
68 *  NOTE: May be unnecessary to reload some registers.
69 */
70
71/*
72 *  void _CPU_Context_restore( new_context )
73 *
74 *  This routine performs a normal non-FP context.
75 */
76
77        PUBLIC (_CPU_Context_restore)
78
79.set NEWCONTEXT_ARG,   4                   # context to restore argument
80
81SYM (_CPU_Context_restore):
82
83        movl      NEWCONTEXT_ARG(esp),eax  # eax = running threads context
84        jmp       restore
85
86/*PAGE
87 *  void _CPU_Context_save_fp_context( &fp_context_ptr )
88 *  void _CPU_Context_restore_fp_context( &fp_context_ptr )
89 *
90 *  This section is used to context switch an i80287, i80387,
91 *  the built-in coprocessor or the i80486 or compatible.
92 */
93
94.set FPCONTEXT_ARG,   4                    # FP context argument
95
96        .p2align  1
97        PUBLIC (_CPU_Context_save_fp)
98SYM (_CPU_Context_save_fp):
99        movl      FPCONTEXT_ARG(esp),eax   # eax = &ptr to FP context area
100        movl      (eax),eax                # eax = FP context area
101        fsave     (eax)                    # save FP context
102        ret
103
104        .p2align  1
105        PUBLIC (_CPU_Context_restore_fp)
106SYM (_CPU_Context_restore_fp):
107        movl      FPCONTEXT_ARG(esp),eax   # eax = &ptr to FP context area
108        movl      (eax),eax                # eax = FP context area
109        frstor    (eax)                    # restore FP context
110        ret
111
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 *  GO32 does not require these segment related routines.
213 */
214
215#ifndef __GO32__
216
217/*
218 *  void *i386_Logical_to_physical(
219 *     rtems_unsigned16  segment,
220 *     void             *address
221 *  );
222 *
223 *  Returns thirty-two bit physical address for segment:address.
224 */
225
226.set SEGMENT_ARG, 4
227.set ADDRESS_ARG, 8
228
229             PUBLIC (i386_Logical_to_physical)
230
231SYM (i386_Logical_to_physical):
232
233        xorl    eax,eax                # clear eax
234        movzwl  SEGMENT_ARG(esp),ecx   # ecx = segment value
235        movl    $ SYM (_Global_descriptor_table),edx
236                                       # edx = address of our GDT
237        addl    ecx,edx                # edx = address of desired entry
238        movb    7(edx),ah              # ah = base 31:24
239        movb    4(edx),al              # al = base 23:16
240        shll    $16,eax                # move ax into correct bits
241        movw    2(edx),ax              # ax = base 0:15
242        movl    ADDRESS_ARG(esp),ecx   # ecx = address to convert
243        addl    eax,ecx                # ecx = physical address equivalent
244        movl    ecx,eax                # eax = ecx
245        ret
246
247/*
248 *  void *i386_Physical_to_logical(
249 *     rtems_unsigned16  segment,
250 *     void             *address
251 *  );
252 *
253 *  Returns thirty-two bit physical address for segment:address.
254 */
255
256/*
257 *.set SEGMENT_ARG, 4
258 *.set ADDRESS_ARG, 8   -- use sets from above
259 */
260
261       PUBLIC (i386_Physical_to_logical)
262
263SYM (i386_Physical_to_logical):
264        xorl    eax,eax                # clear eax
265        movzwl  SEGMENT_ARG(esp),ecx   # ecx = segment value
266        movl    $ SYM (_Global_descriptor_table),edx
267                                       # edx = address of our GDT
268        addl    ecx,edx                # edx = address of desired entry
269        movb    7(edx),ah              # ah = base 31:24
270        movb    4(edx),al              # al = base 23:16
271        shll    $16,eax                # move ax into correct bits
272        movw    2(edx),ax              # ax = base 0:15
273        movl    ADDRESS_ARG(esp),ecx   # ecx = address to convert
274        subl    eax,ecx                # ecx = logical address equivalent
275        movl    ecx,eax                # eax = ecx
276        ret
277#endif /* __GO32__ */
278
279END_CODE
280
281END
Note: See TracBrowser for help on using the repository browser.