source: rtems/c/src/exec/score/cpu/i960/cpu_asm.S @ f2180e0f

4.104.114.84.95
Last change on this file since f2180e0f was f2180e0f, checked in by Joel Sherrill <joel.sherrill@…>, on 08/18/99 at 20:00:05

Patch from Jimen Ching <jimen@…>:

Please take a look at this new patch. It contains a cleaner implementation
of the reset operation. These patches are against 4.0.0. But the files
did not change from the 3.6.0 release. Also, the cpu.h patch below still
applies. I.e. instead of using i960ca_PRCB, use i960_PRCB.

Explanation:

The previous patch removed the use of the reset instruction,
because it always fails. But this was due to the fact that
some of the registers were corrupted by the re-init procedure.
The new patches save and restore those registers when a re-init
is done.

  • Property mode set to 100644
File size: 8.5 KB
Line 
1/*  cpu_asm.s
2 *
3 *  This file contains all assembly code for the i960CA 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        .data
17        .align 4
18_soft_reset_reg_save:
19        .word  0
20        .word  0
21        .word  0
22        .word  0
23_ISR_reg_save:
24        .word  0
25        .word  0
26        .word  0
27        .word  0
28        .word  0
29        .word  0
30
31          .text
32/*
33 * Format of i960ca Register structure
34 */
35
36.set REG_R0_PFP    , 0                # (r0)  Previous Frame Pointer
37.set REG_R1_SP     , REG_R0_PFP+4     # (r1)  Stack Pointer
38.set REG_PC        , REG_R1_SP+4      # (pc)  Processor Controls
39.set REG_G8        , REG_PC+4         # (g8)  Global Register 8
40.set REG_G9        , REG_G8+4         # (g9)  Global Register 9
41.set REG_G10       , REG_G9+4         # (g10) Global Register 10
42.set REG_G11       , REG_G10+4        # (g11) Global Register 11
43.set REG_G12       , REG_G11+4        # (g12) Global Register 12
44.set REG_G13       , REG_G12+4        # (g13) Global Register 13
45.set REG_G14       , REG_G13+4        # (g14) Global Register 14
46.set REG_G15_FP    , REG_G14+4        # (g15) Global Register 15
47.set SIZE_REGS     , REG_G15_FP+4     # size of cpu_context_registers
48                                      #    structure
49
50/*
51 *  void _CPU_Context_switch( run_context, heir_context )
52 *
53 *  This routine performs a normal non-FP context.
54 */
55          .align    4
56          .globl    __CPU_Context_switch
57
58__CPU_Context_switch:
59          modpc     0,0,g2                   # get old intr level (PC)
60          st        g2,REG_PC(g0)            # save pc
61          stq       g8,REG_G8(g0)            # save g8-g11
62          stq       g12,REG_G12(g0)          # save g12-g15
63          stl       pfp,REG_R0_PFP(g0)       # save pfp, sp
64
65restore:  flushreg                           # flush register cache
66          ldconst   0x001f0000,g2            # g2 = PC mask
67          ld        REG_PC(g1),g3            # thread->Regs.pc = pc;
68          ldq       REG_G12(g1),g12          # restore g12-g15
69          ldl       REG_R0_PFP(g1),pfp       # restore pfp, sp
70          ldq       REG_G8(g1),g8            # restore g8-g11
71          modpc     0,g2,g3                  # restore PC register
72          ret
73
74/*
75 *  void _CPU_Context_restore( new_context )
76 *
77 *  This routine performs a normal non-FP context.
78 */
79
80        .globl __CPU_Context_restore
81__CPU_Context_restore:
82          mov       g0,g1                    # g0 = _Thread_executing
83          b         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 *  There is currently no hardware floating point for the i960.
90 */
91
92          .globl    __CPU_Context_save_fp
93          .globl    __CPU_Context_restore_fp
94__CPU_Context_save_fp:
95__CPU_Context_restore_fp:
96#if ( I960_HAS_FPU == 1 )
97#error "Floating point support for i960 family has been implemented!!!"
98#endif
99          ret
100
101/*PAGE
102 *  void __ISR_Handler()
103 *
104 *  This routine provides the RTEMS interrupt management.
105 *
106 *  Input parameters:  NONE
107 *
108 *  Output parameters:  NONE
109 *
110 *  NOTE:
111 *    Upon entry, the supervisor stack will contain a stack frame
112 *    back to the interrupted thread and the interrupt stack will contain
113 *    an interrupt stack frame.  If dispatching is enabled, this
114 *    is the outer most interrupt, and (a context switch is necessary or
115 *    the current thread has signals), then set up the supervisor stack to
116 *    transfer control to the interrupt dispatcher.
117 */
118
119          .globl    __ISR_Handler
120__ISR_Handler:
121          #ldconst 1,r8
122          #modpc   0,r8,r8     # enable tracing
123
124                               # r4 = &_Thread_Dispatch_disable_level
125          ld         __Thread_Dispatch_disable_level,r4
126          movl      g0,r8                    # save g0-g1
127
128          ld        -16+8(fp),g0             # g0 = vector number
129          movl      g2,r10                   # save g2-g3
130
131          ld         __ISR_Nest_level,r5     # r5 = &_Isr_nest_level
132          mov       g14,r7                   # save g14
133
134          lda       0,g14                    # NOT Branch and Link
135          movl      g4,r12                   # save g4-g5
136
137          lda       1(r4),r4                 # increment dispatch disable level
138          movl      g6,r14                   # save g6-g7
139
140                  stq           g8, _ISR_reg_save                # save g8-g11
141                  stl           g12, _ISR_reg_save+16    # save g12-g13
142
143          ld        __ISR_Vector_table[g0*4],g1    # g1 = Users handler
144          addo      1,r5,r5                  # increment ISR level
145
146          st        r4,__Thread_Dispatch_disable_level
147                                             # one ISR nest level deeper
148          subo      1,r4,r4                  # decrement dispatch disable level
149
150          st        r5,__ISR_Nest_level      # disable multitasking
151          subo      1,r5,r5                  # decrement ISR nest level
152
153          callx     (g1)                     # invoke user ISR
154
155          st        r4,__Thread_Dispatch_disable_level
156                                             # unnest multitasking
157          st        r5,__ISR_Nest_level      # one less ISR nest level
158          cmpobne.f 0,r4,exit                # If dispatch disabled, exit
159          ldl       -16(fp),g0               # g0 = threads PC reg
160                                             # g1 = threads AC reg
161          ld        __Context_Switch_necessary,r6
162                                             # r6 = Is thread switch necessary?
163          bbs.f     13,g0,exit               # not outer level, then exit
164          cmpobne.f 0,r6,bframe              # Switch necessary?
165
166          ld        __ISR_Signals_to_thread_executing,g2
167                                             # signals sent to Run_thread
168                                             #   while in interrupt handler?
169          cmpobe.f  0,g2,exit                # No, then exit
170
171bframe:   mov       0,g2
172          st        g2,__ISR_Signals_to_thread_executing
173
174          ldconst   0x1f0000,g2              # g2 = intr disable mask
175          mov       g2,g3                    # g3 = new intr level
176          modpc     0,g2,g3                  # set new level
177
178          andnot    7,pfp,r4                 # r4 = pfp without ret type
179          flushreg                           # flush registers
180                                             # push _Isr_dispatch ret frame
181                                             #   build ISF in r4-r6
182          ldconst   64,g2                    # g2 = size of stack frame
183          ld        4(r4),g3                 # g3 = previous sp
184          addo      g2,g3,r5                 # r5 = _Isr_dispatch SP
185          lda       __ISR_Dispatch,r6        # r6 = _Isr_dispatch entry
186          stt       r4,(g3)                  # set _Isr_dispatch ret info
187          st        g1,16(g3)                # set r4 = AC for ISR disp
188          or        7,g3,pfp                 # pfp to _Isr_dispatch
189
190exit:     mov       r7,g14                   # restore g14
191          movq      r8,g0                    # restore g0-g3
192          movq      r12,g4                   # restore g4-g7
193                  ldq           _ISR_reg_save, g8                # restore g8-g11
194                  ldl           _ISR_reg_save+16, g12    # restore g12-g13
195          ret
196
197
198/*PAGE
199 *
200 *  void __ISR_Dispatch()
201 *
202 *  Entry point from the outermost interrupt service routine exit.
203 *  The current stack is the supervisor mode stack.
204 */
205
206__ISR_Dispatch:
207        mov       g14,r7
208        mov       0,g14
209        movq      g0,r8
210        movq      g4,r12
211        call      __Thread_Dispatch
212
213        ldconst   -1,r5                    # r5 = reload mask
214        modac     r5,r4,r4                 # restore threads AC register
215        mov       r7,g14
216        movq      r8,g0
217        movq      r12,g4
218        ret
219
220
221/*PAGE
222 *
223 *  void __i960_soft_reset_asm
224 *
225 *  Flush the register cache and save the important (fp, pfp, sp) registers,
226 *  which are clobbered by the reinit operation. (Not documented, but it happens).
227 */
228
229                .globl __i960_soft_reset_asm
230__i960_soft_reset_asm:
231                flushreg                                                                # flush register cache
232                mov                     fp, r4
233                mov                     pfp, r5
234                mov                     sp, r6
235                stt                     r4, _soft_reset_reg_save    # save fp, pfp, sp
236                lda                     __i960_reset_done, r4
237                ldconst         0x300, r5
238                sysctl          r5, r4, g0                  # reinit: clobbers almost all registers
239__i960_reset_done:
240                ldt             _soft_reset_reg_save, r4    # restore fp, pfp, sp
241                mov                     r4, fp
242                mov                     r5, pfp
243                mov                     r6, sp
244                ret
Note: See TracBrowser for help on using the repository browser.