source: rtems/c/src/lib/libcpu/sh/sh7032/score/cpu_asm.c @ e96a950b

4.104.114.84.95
Last change on this file since e96a950b was e96a950b, checked in by Ralf Corsepius <ralf.corsepius@…>, on 03/31/04 at 02:00:03

2004-03-30 Ralf Corsepius <ralf_corsepius@…>

  • sh7032/clock/ckinit.c, sh7032/delay/delay.c, sh7032/include/ispsh7032.h, sh7032/sci/sci.c, sh7032/score/cpu_asm.c, sh7032/timer/timer.c, sh7045/clock/ckinit.c, sh7045/include/ispsh7045.h, sh7045/sci/sci.c, sh7045/sci/sci_termios.c, sh7045/score/cpu_asm.c, sh7045/timer/timer.c, sh7750/clock/ckinit.c, sh7750/include/rtems/score/ispsh7750.h, sh7750/include/sh/sh4uart.h, sh7750/sci/sh4uart.c, sh7750/score/cpu_asm.c, sh7750/score/ispsh7750.c, sh7750/timer/timer.c: Convert to using c99 fixed size types.
  • Property mode set to 100644
File size: 6.8 KB
Line 
1/*
2 *  This file contains the basic algorithms for all assembly code used
3 *  in an specific CPU port of RTEMS.  These algorithms must be implemented
4 *  in assembly language
5 *
6 *  NOTE:  This port uses a C file with inline assembler instructions
7 *
8 *  Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
9 *           Bernd Becker (becker@faw.uni-ulm.de)
10 *
11 *  COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
12 *
13 *  This program is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 *
17 *
18 *  COPYRIGHT (c) 1998.
19 *  On-Line Applications Research Corporation (OAR).
20 *
21 *  The license and distribution terms for this file may be
22 *  found in the file LICENSE in this distribution or at
23 *  http://www.rtems.com/license/LICENSE.
24 *
25 *  $Id$
26 *
27 */
28
29/*
30 *  This is supposed to be an assembly file.  This means that system.h
31 *  and cpu.h should not be included in a "real" cpu_asm file.  An
32 *  implementation in assembly should include "cpu_asm.h"
33 */
34
35#include <rtems/system.h>
36#include <rtems/score/cpu.h>
37#include <rtems/score/isr.h>
38#include <rtems/score/thread.h>
39#include <rtems/score/sh.h>
40
41#include <rtems/score/ispsh7032.h>
42#include <rtems/score/iosh7032.h>
43#include <rtems/score/sh_io.h>
44
45/* from cpu_isps.c */
46extern proc_ptr         _Hardware_isr_Table[];
47
48#if( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
49  unsigned long    *_old_stack_ptr;
50#endif
51
52register unsigned long  *stack_ptr asm("r15");
53
54/*
55 * sh_set_irq_priority
56 *
57 * this function sets the interrupt level of the specified interrupt
58 *
59 * parameters:
60 *             - irq : interrupt number
61 *             - prio: priority to set for this interrupt number
62 *
63 * returns:    0 if ok
64 *             -1 on error
65 */
66
67unsigned int sh_set_irq_priority(
68  unsigned int irq,
69  unsigned int prio )
70{
71  uint32_t   shiftcount;
72  uint32_t   prioreg;
73  uint16_t   temp16;
74  uint32_t   level;
75
76  /*
77   * first check for valid interrupt
78   */
79  if(( irq > 113) || (_Hardware_isr_Table[irq] == _dummy_isp))
80    return -1;
81  /*
82   * check for valid irq priority
83   */
84  if( prio > 15 )
85    return -1;
86
87  /*
88   * look up appropriate interrupt priority register
89   */
90  if( irq > 71)
91    {
92      irq = irq - 72;
93      shiftcount = 12 - ((irq & ~0x03) % 16);
94     
95      switch( irq / 16)
96        {
97        case 0: { prioreg = INTC_IPRC; break;}
98        case 1: { prioreg = INTC_IPRD; break;}
99        case 2: { prioreg = INTC_IPRE; break;}
100        default: return -1;
101        }
102    }
103  else
104    {
105      shiftcount = 12 - 4 * ( irq % 4);
106      if( irq > 67)
107        prioreg = INTC_IPRB;
108      else
109        prioreg = INTC_IPRA;
110    }
111
112  /*
113   * Set the interrupt priority register
114   */
115  _CPU_ISR_Disable( level );
116
117  temp16 = read16( prioreg);
118  temp16 &= ~( 15 << shiftcount);
119  temp16 |= prio << shiftcount;
120  write16( temp16, prioreg);
121
122  _CPU_ISR_Enable( level );
123
124  return 0;
125}
126
127/*
128 *  _CPU_Context_save_fp_context
129 *
130 *  This routine is responsible for saving the FP context
131 *  at *fp_context_ptr.  If the point to load the FP context
132 *  from is changed then the pointer is modified by this routine.
133 *
134 *  Sometimes a macro implementation of this is in cpu.h which dereferences
135 *  the ** and a similarly named routine in this file is passed something
136 *  like a (Context_Control_fp *).  The general rule on making this decision
137 *  is to avoid writing assembly language.
138 */
139
140void _CPU_Context_save_fp(
141  void **fp_context_ptr
142)
143{
144}
145
146/*
147 *  _CPU_Context_restore_fp_context
148 *
149 *  This routine is responsible for restoring the FP context
150 *  at *fp_context_ptr.  If the point to load the FP context
151 *  from is changed then the pointer is modified by this routine.
152 *
153 *  Sometimes a macro implementation of this is in cpu.h which dereferences
154 *  the ** and a similarly named routine in this file is passed something
155 *  like a (Context_Control_fp *).  The general rule on making this decision
156 *  is to avoid writing assembly language.
157 */
158
159void _CPU_Context_restore_fp(
160  void **fp_context_ptr
161)
162{
163}
164
165/*  _CPU_Context_switch
166 *
167 *  This routine performs a normal non-FP context switch.
168 */
169
170/*  within __CPU_Context_switch:
171 *  _CPU_Context_switch
172 *  _CPU_Context_restore
173 *
174 *  This routine is generally used only to restart self in an
175 *  efficient manner.  It may simply be a label in _CPU_Context_switch.
176 *
177 * NOTE: It should be safe not to store r4, r5
178 *
179 * NOTE: It is doubtful if r0 is really needed to be stored
180 *
181 * NOTE: gbr is added, but should not be necessary, as it is
182 *      only used globally in this port.
183 */
184
185/*
186 * FIXME: This is an ugly hack, but we wanted to avoid recalculating
187 *        the offset each time Context_Control is changed
188 */
189void __CPU_Context_switch(
190  Context_Control  *run,        /* r4 */
191  Context_Control  *heir        /* r5 */
192)
193{
194
195asm volatile(
196        ".global __CPU_Context_switch\n"
197"__CPU_Context_switch:\n"
198
199"       add     %0,r4\n"
200 
201"       stc.l   sr,@-r4\n"
202"       stc.l   gbr,@-r4\n"
203"       mov.l   r0,@-r4\n"
204"       mov.l   r1,@-r4\n"
205"       mov.l   r2,@-r4\n"
206"       mov.l   r3,@-r4\n"
207
208"       mov.l   r6,@-r4\n"
209"       mov.l   r7,@-r4\n"
210"       mov.l   r8,@-r4\n"
211"       mov.l   r9,@-r4\n"
212"       mov.l   r10,@-r4\n"
213"       mov.l   r11,@-r4\n"
214"       mov.l   r12,@-r4\n"
215"       mov.l   r13,@-r4\n"
216"       mov.l   r14,@-r4\n"
217"       sts.l   pr,@-r4\n"
218"       sts.l   mach,@-r4\n"
219"       sts.l   macl,@-r4\n"
220"       mov.l   r15,@-r4\n"
221
222"       mov     r5, r4\n"
223  :: "i" (sizeof(Context_Control))
224  );
225
226  asm volatile(
227        ".global __CPU_Context_restore\n"
228"__CPU_Context_restore:\n"
229"       mov.l   @r4+,r15\n"
230"       lds.l   @r4+,macl\n"
231"       lds.l   @r4+,mach\n"
232"       lds.l   @r4+,pr\n"
233"       mov.l   @r4+,r14\n"
234"       mov.l   @r4+,r13\n"
235"       mov.l   @r4+,r12\n"
236"       mov.l   @r4+,r11\n"
237"       mov.l   @r4+,r10\n"
238"       mov.l   @r4+,r9\n"
239"       mov.l   @r4+,r8\n"
240"       mov.l   @r4+,r7\n"
241"       mov.l   @r4+,r6\n"
242
243"       mov.l   @r4+,r3\n"
244"       mov.l   @r4+,r2\n"
245"       mov.l   @r4+,r1\n"
246"       mov.l   @r4+,r0\n"
247"       ldc.l   @r4+,gbr\n"
248"       ldc.l   @r4+,sr\n"
249
250"       rts\n"
251"       nop\n" );
252}
253
254/* 
255 *  This routine provides the RTEMS interrupt management.
256 */
257 
258void __ISR_Handler( uint32_t   vector)
259{
260  register uint32_t   level;
261
262  _CPU_ISR_Disable( level );
263
264  _Thread_Dispatch_disable_level++;
265
266#if( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
267  if( _ISR_Nest_level == 0 )
268    {
269      /* Install irq stack */
270      _old_stack_ptr = stack_ptr;
271      stack_ptr = _CPU_Interrupt_stack_high;
272    }
273
274#endif
275
276  _ISR_Nest_level++;
277
278  _CPU_ISR_Enable( level );
279
280  /* call isp */
281  if( _ISR_Vector_table[ vector])
282    (*_ISR_Vector_table[ vector ])( vector );
283
284  _CPU_ISR_Disable( level );
285
286  _Thread_Dispatch_disable_level--;
287
288  _ISR_Nest_level--;
289
290#if( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
291
292  if( _ISR_Nest_level == 0 )
293    /* restore old stack pointer */
294    stack_ptr = _old_stack_ptr; 
295#endif
296
297  _CPU_ISR_Enable( level );
298
299  if ( _ISR_Nest_level )
300    return;
301
302  if ( _Thread_Dispatch_disable_level ) {
303    _ISR_Signals_to_thread_executing = FALSE;
304    return;
305  }
306
307  if ( _Context_Switch_necessary || _ISR_Signals_to_thread_executing ) {
308    _ISR_Signals_to_thread_executing = FALSE;
309    _Thread_Dispatch();
310  }
311}
Note: See TracBrowser for help on using the repository browser.