Back to home page

LXR

 
 

    


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

0001 /**
0002  * @file
0003  *
0004  * @brief SuperH CPU Support
0005  *
0006  * This file contains information pertaining to the Hitachi SH
0007  * processor.
0008  */
0009 
0010 /*
0011  *  Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
0012  *           Bernd Becker (becker@faw.uni-ulm.de)
0013  *
0014  *  COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
0015  *
0016  *  This program is distributed in the hope that it will be useful,
0017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
0019  *
0020  *
0021  *  COPYRIGHT (c) 1998-2001.
0022  *  On-Line Applications Research Corporation (OAR).
0023  *
0024  *  The license and distribution terms for this file may be
0025  *  found in the file LICENSE in this distribution or at
0026  *  http://www.rtems.org/license/LICENSE.
0027  */
0028 
0029 #ifdef HAVE_CONFIG_H
0030 #include "config.h"
0031 #endif
0032 
0033 #include <rtems/score/cpuimpl.h>
0034 #include <rtems/score/isr.h>
0035 #include <rtems/score/sh_io.h>
0036 #include <rtems/score/sh.h>
0037 
0038 /* referenced in start.S */
0039 CPU_ISR_raw_handler vectab[256] ;
0040 
0041 #if SH_HAS_FPU
0042 Context_Control_fp _CPU_Null_fp_context;
0043 #endif
0044 
0045 /*  _CPU_Initialize
0046  *
0047  *  This routine performs processor dependent initialization.
0048  *
0049  *  INPUT PARAMETERS: NONE
0050  */
0051 
0052 void _CPU_Initialize(void)
0053 {
0054   register uint32_t   level = 0;
0055 
0056   /*
0057    *  If there is not an easy way to initialize the FP context
0058    *  during Context_Initialize, then it is usually easier to
0059    *  save an "uninitialized" FP context here and copy it to
0060    *  the task's during Context_Initialize.
0061    */
0062 
0063   /* FP context initialization support goes here */
0064 #if SH_HAS_FPU
0065   /* FIXME: When not to use SH4_FPSCR_PR ? */
0066 #ifdef __SH4__
0067   _CPU_Null_fp_context.fpscr = SH4_FPSCR_DN | SH4_FPSCR_RM | SH4_FPSCR_PR;
0068 #endif
0069 #ifdef __SH3E__
0070   /* FIXME: Wild guess :) */
0071   _CPU_Null_fp_context.fpscr = SH4_FPSCR_DN | SH4_FPSCR_RM;
0072 #endif
0073 #endif
0074 
0075   /* enable interrupts */
0076   _CPU_ISR_Set_level( level ) ;
0077 }
0078 
0079 /*
0080  *  _CPU_ISR_Get_level
0081  */
0082 
0083 uint32_t   _CPU_ISR_Get_level( void )
0084 {
0085   /*
0086    *  This routine returns the current interrupt level.
0087    */
0088 
0089   register uint32_t   _mask ;
0090 
0091   sh_get_interrupt_level( _mask );
0092 
0093   return ( _mask);
0094 }
0095 
0096 void _CPU_ISR_install_raw_handler(
0097   uint32_t             vector,
0098   CPU_ISR_raw_handler  new_handler,
0099   CPU_ISR_raw_handler *old_handler
0100 )
0101 
0102 {
0103   /*
0104    *  This is where we install the interrupt handler into the "raw" interrupt
0105    *  table used by the CPU to dispatch interrupt handlers.
0106    */
0107   volatile CPU_ISR_raw_handler *vbr ;
0108 
0109 #if SH_PARANOID_ISR
0110   uint32_t          level ;
0111 
0112   sh_disable_interrupts( level );
0113 #endif
0114 
0115   /* get vbr */
0116   __asm__ ( "stc vbr,%0" : "=r" (vbr) );
0117 
0118   *old_handler = vbr[vector] ;
0119   vbr[vector]  = new_handler ;
0120 
0121 #if SH_PARANOID_ISR
0122   sh_enable_interrupts( level );
0123 #endif
0124 }
0125 
0126 void _CPU_ISR_install_vector(
0127   uint32_t         vector,
0128   CPU_ISR_handler  new_handler,
0129   CPU_ISR_handler *old_handler
0130 )
0131 {
0132 #if defined(__sh1__) || defined(__sh2__)
0133    CPU_ISR_raw_handler ignored ;
0134 #endif
0135    *old_handler = _ISR_Vector_table[ vector ];
0136 
0137  /*
0138   *  If the interrupt vector table is a table of pointer to isr entry
0139   *  points, then we need to install the appropriate RTEMS interrupt
0140   *  handler for this vector number.
0141   */
0142 #if defined(__sh1__) || defined(__sh2__)
0143   _CPU_ISR_install_raw_handler(vector, _Hardware_isr_Table[vector], &ignored );
0144 #endif
0145 
0146  /*
0147   *  We put the actual user ISR address in '_ISR_Vector_table'.
0148   *  This will be used by __ISR_Handler so the user gets control.
0149   */
0150 
0151  _ISR_Vector_table[ vector ] = new_handler;
0152 }
0153 
0154 void _CPU_Context_Initialize(
0155   Context_Control   *_the_context,
0156   void          *_stack_base,
0157   uint32_t          _size,
0158   uint32_t          _isr,
0159   void  (*_entry_point)(void),
0160   int           _is_fp,
0161   void          *_tls_base)
0162 {
0163   _the_context->r15 = (uint32_t *) ((uint32_t) (_stack_base) + (_size) );
0164 #if defined(__sh1__) || defined(__sh2__) || defined(__SH2E__)
0165   _the_context->sr  = (_isr << 4) & 0x00f0 ;
0166 #else
0167   _the_context->sr  = SH4_SR_MD | ((_isr << 4) & 0x00f0);
0168 #endif
0169   _the_context->pr  = (uint32_t *) _entry_point ;
0170 
0171 
0172 #if 0 && SH_HAS_FPU
0173    /* Disable FPU if it is non-fp task */
0174   if(!_is_fp)
0175     _the_context->sr |= SH4_SR_FD;
0176 #endif
0177 }