Back to home page

LXR

 
 

    


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

0001 /*
0002  *  This file contains the basic algorithms for all assembly code used
0003  *  in an specific CPU port of RTEMS.  These algorithms must be implemented
0004  *  in assembly language
0005  *
0006  *  NOTE:  This port uses a C file with inline assembler instructions
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  *
0018  *  COPYRIGHT (c) 1998.
0019  *  On-Line Applications Research Corporation (OAR).
0020  *
0021  *  The license and distribution terms for this file may be
0022  *  found in the file LICENSE in this distribution or at
0023  *  http://www.rtems.org/license/LICENSE.
0024  */
0025 
0026 /*
0027  *  This is supposed to be an assembly file.  This means that system.h
0028  *  and cpu.h should not be included in a "real" cpu_asm file.  An
0029  *  implementation in assembly should include "cpu_asm.h"
0030  */
0031 
0032 #include <rtems/score/cpu.h>
0033 #include <rtems/score/isr.h>
0034 #include <rtems/score/threaddispatch.h>
0035 #include <rtems/score/sh.h>
0036 
0037 #include <rtems/score/ispsh7045.h>
0038 #include <rtems/score/iosh7045.h>
0039 #include <rtems/score/sh_io.h>
0040 
0041 unsigned long *_old_stack_ptr;
0042 
0043 register unsigned long  *stack_ptr __asm__ ("r15");
0044 
0045 /*
0046  * sh_set_irq_priority
0047  *
0048  * this function sets the interrupt level of the specified interrupt
0049  *
0050  * parameters:
0051  *             - irq : interrupt number
0052  *             - prio: priority to set for this interrupt number
0053  *
0054  * returns:    0 if ok
0055  *             -1 on error
0056  */
0057 
0058 unsigned int sh_set_irq_priority(
0059   unsigned int irq,
0060   unsigned int prio )
0061 {
0062   uint32_t   shiftcount;
0063   uint32_t   prioreg;
0064   uint16_t   temp16;
0065   ISR_Level  level;
0066 
0067   /*
0068    * first check for valid interrupt
0069    */
0070   if (( irq > 156) || (irq < 64) || (_Hardware_isr_Table[irq] == _dummy_isp))
0071     return -1;
0072   /*
0073    * check for valid irq priority
0074    */
0075   if ( prio > 15 )
0076     return -1;
0077 
0078   /*
0079    * look up appropriate interrupt priority register
0080    */
0081   if ( irq > 71)
0082     {
0083       irq = irq - 72;
0084       shiftcount = 12 - ((irq & ~0x03) % 16);
0085 
0086       switch( irq / 16)
0087     {
0088     case 0: { prioreg = INTC_IPRC; break;}
0089     case 1: { prioreg = INTC_IPRD; break;}
0090     case 2: { prioreg = INTC_IPRE; break;}
0091     case 3: { prioreg = INTC_IPRF; break;}
0092     case 4: { prioreg = INTC_IPRG; break;}
0093     case 5: { prioreg = INTC_IPRH; break;}
0094     default: return -1;
0095     }
0096     }
0097   else
0098     {
0099       shiftcount = 12 - 4 * ( irq % 4);
0100       if ( irq > 67)
0101     prioreg = INTC_IPRB;
0102       else
0103     prioreg = INTC_IPRA;
0104     }
0105 
0106   /*
0107    * Set the interrupt priority register
0108    */
0109   _ISR_Local_disable( level );
0110 
0111     temp16 = read16( prioreg);
0112     temp16 &= ~( 15 << shiftcount);
0113     temp16 |= prio << shiftcount;
0114     write16( temp16, prioreg);
0115 
0116   _ISR_Local_enable( level );
0117 
0118   return 0;
0119 }
0120 
0121 /*
0122  *  This routine provides the RTEMS interrupt management.
0123  */
0124 
0125 void __ISR_Handler( uint32_t   vector)
0126 {
0127   ISR_Level level;
0128 
0129   _ISR_Local_disable( level );
0130 
0131   _Thread_Dispatch_disable();
0132 
0133   if ( _ISR_Nest_level == 0 )
0134     {
0135       /* Install irq stack */
0136       _old_stack_ptr = stack_ptr;
0137       stack_ptr = _CPU_Interrupt_stack_high;
0138     }
0139 
0140   _ISR_Nest_level++;
0141 
0142   _ISR_Local_enable( level );
0143 
0144   /* call isp */
0145   if ( _ISR_Vector_table[ vector])
0146     (*_ISR_Vector_table[ vector ])( vector );
0147 
0148   _ISR_Local_disable( level );
0149 
0150   _Thread_Dispatch_unnest( _Per_CPU_Get() );
0151 
0152   _ISR_Nest_level--;
0153 
0154   if ( _ISR_Nest_level == 0 )
0155     /* restore old stack pointer */
0156     stack_ptr = _old_stack_ptr;
0157 
0158   _ISR_Local_enable( level );
0159 
0160   if ( _ISR_Nest_level )
0161     return;
0162 
0163   if ( !_Thread_Dispatch_is_enabled() ) {
0164     return;
0165   }
0166 
0167   if ( _Thread_Dispatch_necessary ) {
0168     _Thread_Dispatch();
0169   }
0170 }