Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:25

0001 /**
0002  * @file
0003  *
0004  * @brief SuperH CPU Context
0005  */
0006 
0007 /*
0008  *  Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
0009  *           Bernd Becker (becker@faw.uni-ulm.de)
0010  *
0011  *  COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
0012  *
0013  *  This program is distributed in the hope that it will be useful,
0014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
0016  *
0017  *  COPYRIGHT (c) 1998.
0018  *  On-Line Applications Research Corporation (OAR).
0019  *
0020  *  The license and distribution terms for this file may be
0021  *  found in the file LICENSE in this distribution or at
0022  *  http://www.rtems.org/license/LICENSE.
0023  */
0024 
0025 #ifdef HAVE_CONFIG_H
0026 #include "config.h"
0027 #endif
0028 
0029 #include <rtems/score/cpu.h>
0030 #include <rtems/score/isr.h>
0031 #include <rtems/score/thread.h>
0032 #include <rtems/score/sh.h>
0033 
0034 /*
0035  *  _CPU_Context_save_fp_context
0036  *
0037  *  This routine is responsible for saving the FP context
0038  *  at *fp_context_ptr.  If the point to load the FP context
0039  *  from is changed then the pointer is modified by this routine.
0040  *
0041  *  Sometimes a macro implementation of this is in cpu.h which dereferences
0042  *  the ** and a similarly named routine in this file is passed something
0043  *  like a (Context_Control_fp *).  The general rule on making this decision
0044  *  is to avoid writing assembly language.
0045  */
0046 
0047 void _CPU_Context_save_fp(
0048   Context_Control_fp **fp_context_ptr
0049 )
0050 {
0051 #if SH_HAS_FPU
0052 
0053 asm volatile("\n\
0054     mov.l   @%0,r4    \n\
0055     add     %1,r4\n\
0056     sts.l   fpscr,@-r4\n\
0057     sts.l   fpul,@-r4\n\
0058     lds     %2,fpscr\n\
0059     fmov    dr14,@-r4\n\
0060     fmov    dr12,@-r4\n\
0061     fmov    dr10,@-r4\n\
0062     fmov    dr8,@-r4\n\
0063     fmov    dr6,@-r4\n\
0064     fmov    dr4,@-r4\n\
0065     fmov    dr2,@-r4\n\
0066     fmov    dr0,@-r4\n\
0067     "
0068 #ifdef SH4_USE_X_REGISTERS
0069     "\
0070     lds     %3,fpscr\n\
0071     fmov    xd14,@-r4\n\
0072     fmov    xd12,@-r4\n\
0073     fmov    xd10,@-r4\n\
0074     fmov    xd8,@-r4\n\
0075     fmov    xd6,@-r4\n\
0076     fmov    xd4,@-r4\n\
0077     fmov    xd2,@-r4\n\
0078     fmov    xd0,@-r4\n\
0079     "
0080 #endif
0081    "lds     %4,fpscr\n\
0082    "
0083     :
0084     : "r"(fp_context_ptr), "r"(sizeof(Context_Control_fp)),
0085       "r"(SH4_FPSCR_SZ), "r"(SH4_FPSCR_PR | SH4_FPSCR_SZ), "r"(SH4_FPSCR_PR)
0086     : "r4", "r0");
0087 
0088 #endif
0089 
0090 }
0091 
0092 /*
0093  *  _CPU_Context_restore_fp_context
0094  *
0095  *  This routine is responsible for restoring the FP context
0096  *  at *fp_context_ptr.  If the point to load the FP context
0097  *  from is changed then the pointer is modified by this routine.
0098  *
0099  *  Sometimes a macro implementation of this is in cpu.h which dereferences
0100  *  the ** and a similarly named routine in this file is passed something
0101  *  like a (Context_Control_fp *).  The general rule on making this decision
0102  *  is to avoid writing assembly language.
0103  */
0104 
0105 void _CPU_Context_restore_fp(
0106   Context_Control_fp **fp_context_ptr
0107 )
0108 {
0109 
0110 #if SH_HAS_FPU
0111 
0112 asm volatile("\n\
0113     mov.l   @%0,r4    \n\
0114     "
0115 #ifdef SH4_USE_X_REGISTERS
0116     "\n\
0117     lds     %1,fpscr\n\
0118     fmov    @r4+,xd0\n\
0119     fmov    @r4+,xd2\n\
0120     fmov    @r4+,xd4\n\
0121     fmov    @r4+,xd6\n\
0122     fmov    @r4+,xd8\n\
0123     fmov    @r4+,xd10\n\
0124     fmov    @r4+,xd12\n\
0125     fmov    @r4+,xd14\n\
0126     "
0127 #endif
0128     "\n\
0129     lds     %2,fpscr\n\
0130     fmov    @r4+,dr0\n\
0131     fmov    @r4+,dr2\n\
0132     fmov    @r4+,dr4\n\
0133     fmov    @r4+,dr6\n\
0134     fmov    @r4+,dr8\n\
0135     fmov    @r4+,dr10\n\
0136     fmov    @r4+,dr12\n\
0137     fmov    @r4+,dr14\n\
0138     lds.l   @r4+,fpul\n\
0139     lds.l   @r4+,fpscr\n\
0140     " :
0141     : "r"(fp_context_ptr), "r"(SH4_FPSCR_PR | SH4_FPSCR_SZ), "r"(SH4_FPSCR_SZ)
0142     : "r4", "r0");
0143 #endif
0144 }
0145 
0146 /*  _CPU_Context_switch
0147  *
0148  *  This routine performs a normal non-FP context switch.
0149  */
0150 
0151 /*  within __CPU_Context_switch:
0152  *  _CPU_Context_switch
0153  *  _CPU_Context_restore
0154  *
0155  *  This routine is generally used only to restart self in an
0156  *  efficient manner.  It may simply be a label in _CPU_Context_switch.
0157  *
0158  * NOTE: It should be safe not to store r4, r5
0159  *
0160  * NOTE: It is doubtful if r0 is really needed to be stored
0161  *
0162  * NOTE: gbr is added, but should not be necessary, as it is
0163  *  only used globally in this port.
0164  */
0165 
0166 /*
0167  * FIXME: This is an ugly hack, but we wanted to avoid recalculating
0168  *        the offset each time Context_Control is changed
0169  */
0170 void _CPU_Context_switch(
0171   Context_Control  *run,    /* r4 */
0172   Context_Control  *heir    /* r5 */
0173 )
0174 {
0175 
0176 asm volatile("\n\
0177     .global __CPU_Context_switch\n\
0178 __CPU_Context_switch:\n\
0179 \n\
0180     add %0,r4\n\
0181   \n\
0182     stc.l   sr,@-r4\n\
0183     stc.l   gbr,@-r4\n\
0184     mov.l   r0,@-r4\n\
0185     mov.l   r1,@-r4\n\
0186     mov.l   r2,@-r4\n\
0187     mov.l   r3,@-r4\n\
0188 \n\
0189     mov.l   r6,@-r4\n\
0190     mov.l   r7,@-r4\n\
0191     mov.l   r8,@-r4\n\
0192     mov.l   r9,@-r4\n\
0193     mov.l   r10,@-r4\n\
0194     mov.l   r11,@-r4\n\
0195     mov.l   r12,@-r4\n\
0196     mov.l   r13,@-r4\n\
0197     mov.l   r14,@-r4\n\
0198     sts.l   pr,@-r4\n\
0199     sts.l   mach,@-r4\n\
0200     sts.l   macl,@-r4\n\
0201     mov.l   r15,@-r4\n\
0202 \n\
0203     mov     r5, r4"
0204   :: "i" (sizeof(Context_Control))
0205   );
0206 
0207   __asm__ volatile("\n\
0208     .global __CPU_Context_restore\n\
0209 __CPU_Context_restore:\n\
0210     mov.l   @r4+,r15\n\
0211     lds.l   @r4+,macl\n\
0212     lds.l   @r4+,mach\n\
0213     lds.l   @r4+,pr\n\
0214     mov.l   @r4+,r14\n\
0215     mov.l   @r4+,r13\n\
0216     mov.l   @r4+,r12\n\
0217     mov.l   @r4+,r11\n\
0218     mov.l   @r4+,r10\n\
0219     mov.l   @r4+,r9\n\
0220     mov.l   @r4+,r8\n\
0221     mov.l   @r4+,r7\n\
0222     mov.l   @r4+,r6\n\
0223 \n\
0224     mov.l   @r4+,r3\n\
0225     mov.l   @r4+,r2\n\
0226     mov.l   @r4+,r1\n\
0227     mov.l   @r4+,r0\n\
0228     ldc.l   @r4+,gbr\n\
0229     ldc.l   @r4+,sr\n\
0230 \n\
0231     rts\n\
0232     nop" );
0233 }