summaryrefslogblamecommitdiffstats
path: root/cpukit/score/cpu/c4x/rtems/score/c4x.h
blob: d3ef758693e91615d7032d7a799d9e5a988121e4 (plain) (tree)










































































































































































































































































































































                                                                         
                                                  












                                                  

                                                    














                             
/*  c4x.h
 *
 *  This file is an example (i.e. "no CPU") of the file which is
 *  created for each CPU family port of RTEMS.
 *
 *
 *  COPYRIGHT (c) 1989-1999.
 *  On-Line Applications Research Corporation (OAR).
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.OARcorp.com/rtems/license.html.
 *
 *  $Id$
 *
 */

#ifndef _INCLUDE_C4X_h
#define _INCLUDE_C4X_h

#ifdef __cplusplus
extern "C" {
#endif

/*
 *  This file contains the information required to build
 *  RTEMS for a particular member of the "no cpu"
 *  family when executing in protected mode.  It does
 *  this by setting variables to indicate which implementation
 *  dependent features are present in a particular member
 *  of the family.
 */
 
#if defined(c30)
#define CPU_MODEL_NAME  "C30"

#elif defined(c31)
#define CPU_MODEL_NAME  "C31"
 
#elif defined(c32)
#define CPU_MODEL_NAME  "C32"
 
#elif defined(c40)
#define CPU_MODEL_NAME  "C40"
 
#elif defined(c44)
#define CPU_MODEL_NAME  "C44"
 
#else
 
#error "Unsupported CPU Model"
 
#endif

/*
 *  Define the name of the CPU family.
 */

#define CPU_NAME "Texas Instruments C3x/C4x"

/*
 *  This port is a little unusual in that even though there are "floating
 *  point registers", the notion of floating point is very inherent to
 *  applications.  In addition, the calling conventions require that
 *  only a few extended registers be preserved across subroutine calls.
 *  The overhead of including these few registers in the basic 
 *  context is small compared to the overhead of managing the notion
 *  of separate floating point contexts.  So we decided to pretend that
 *  there is no FPU on the C3x or C4x.
 */

#define C4X_HAS_FPU  0

/*
 *  Routines to manipulate the bits in the Status Word (ST).
 */

#define C4X_ST_C      0x0001
#define C4X_ST_V      0x0002
#define C4X_ST_Z      0x0004
#define C4X_ST_N      0x0008
#define C4X_ST_UF     0x0010
#define C4X_ST_LV     0x0020
#define C4X_ST_LUF    0x0040
#define C4X_ST_OVM    0x0080
#define C4X_ST_RM     0x0100
#define C4X_ST_CF     0x0400
#define C4X_ST_CE     0x0800
#define C4X_ST_CC     0x1000
#define C4X_ST_GIE    0x2000

#ifndef _TMS320C40
#define C3X_IE_INTERRUPT_MASK_BITS     0xffff
#define C3x_IE_INTERRUPTS_ALL_ENABLED  0x0000
#define C3x_IE_INTERRUPTS_ALL_DISABLED 0xffff
#endif

#ifndef ASM

/*
 *  A nop macro.
 */

#define c4x_nop() \
  __asm__("nop");

/*
 *  Routines to set and clear individual bits in the ST (status word).
 *
 *  cpu_st_bit_clear  - clear bit in ST
 *  cpu_st_bit_set    - set bit in ST
 *  cpu_st_get        - obtain entire ST
 */

#ifdef _TMS320C40
#define c4x_gie_nop()
#else
#define c4x_gie_nop() { c4x_nop(); c4x_nop(); }
#endif

#define cpu_st_bit_clear(_st_bit) \
  do { \
    __asm__("andn %0,st" : : "g" (_st_bit) : "cc"); \
    c4x_gie_nop(); \
  } while (0)

#define cpu_st_bit_set(_st_bit) \
  do { \
    __asm__("or %0,st" : : "g" (_st_bit) : "cc"); \
    c4x_gie_nop(); \
  } while (0)

static inline unsigned int cpu_st_get(void)
{
  register unsigned int st_value;
  __asm__("ldi st, %0" : "=r" (st_value));
  return st_value;
}

/*
 *  Routines to manipulate the Global Interrupt Enable (GIE) bit in
 *  the Status Word (ST).
 *
 *  c4x_global_interrupts_get      - returns current GIE setting
 *  c4x_global_interrupts_disable  - disables global interrupts
 *  c4x_global_interrupts_enable   - enables global interrupts
 *  c4x_global_interrupts_restore  - restores GIE to pre-disable state
 *  c4x_global_interrupts_flash    - temporarily enable global interrupts
 */

#define c4x_global_interrupts_get() \
  (cpu_st_get() & C4X_ST_GIE)
  
#define c4x_global_interrupts_disable() \
  cpu_st_bit_clear(C4X_ST_GIE)

#define c4x_global_interrupts_enable() \
  cpu_st_bit_set(C4X_ST_GIE)

#define c4x_global_interrupts_restore(_old_level) \
  cpu_st_bit_set(_old_level)

#define c4x_global_interrupts_flash(_old_level) \
  do { \
    cpu_st_bit_set(_old_level); \
    cpu_st_bit_clear(C4X_ST_GIE); \
  } while (0)

#ifndef _TMS320C40

/*
 *  Routines to set and get the IF register
 *
 *  c3x_get_if     - obtains IF register
 *  c3x_set_if     - sets IF register
 */

static inline unsigned int c3x_get_if(void)
{
  register unsigned int _if_value;

  __asm__( "ldi if, %0" : "=r" (_if_value) );
  return _if_value;
}

static inline void c3x_set_if(unsigned int _if_value)
{
  __asm__( "ldi %0, if" : : "g" (_if_value) : "if", "cc"); 
}

/*
 *  Routines to set and get the IE register
 *
 *  c3x_get_ie     - obtains IE register
 *  c3x_set_ie     - sets IE register
 */

static inline unsigned int c3x_get_ie(void)
{
  register unsigned int _ie_value;

  __asm__ volatile ( "ldi ie, %0" : "=r" (_ie_value) );
  return _ie_value;
}

static inline void c3x_set_ie(unsigned int _ie_value)
{
  __asm__ volatile ( "ldi %0, ie" : : "g" (_ie_value) : "ie", "cc"); 
}

/*
 *  Routines to manipulates the mask portion of the IE register.
 *
 *  c3x_ie_mask_all     - returns previous IE mask
 *  c3x_ie_mask_restore - restores previous IE mask
 *  c3x_ie_mask_flash   - temporarily restores previous IE mask
 *  c3x_ie_mask_set     - sets a specific set of the IE mask
 */
 
#define c3x_ie_mask_all( _isr_cookie ) \
  do { \
    __asm__("ldi  ie,%0\n" \
            "\tandn 0ffffh, ie" \
          : "=r" (_isr_cookie): : "ie", "cc" ); \
  } while (0)

#define c3x_ie_mask_restore( _isr_cookie )  \
  do { \
    __asm__("or %0, ie" \
          : : "g" (_isr_cookie) : "ie", "cc" ); \
  } while (0)

#define c3x_ie_mask_flash( _isr_cookie ) \
  do { \
    __asm__("or %0, ie\n" \
           "\tandn 0ffffh, ie" \
          : : "g" (_isr_cookie) : "ie", "cc" ); \
  } while (0)

#define c3x_ie_mask_set( _new_mask ) \
  do { unsigned int _ie_mask; \
    unsigned int _ie_value; \
    \
    if ( _new_mask == 0 ) _ie_mask = 0; \
    else                  _ie_mask = 0xffff; \
    _ie_value = c3x_get_ie(); \
    _ie_value &= C4X_IE_INTERRUPT_MASK_BITS; \
    _ie_value |= _ie_mask; \
    c3x_set_ie(_ie_value); \
  } while (0)
#endif
/* end of C3x specific interrupt flag routines */

/*
 *  This is a section of C4x specific interrupt flag management routines.
 */

#ifdef _TMS320C40

/*
 *  Routines to set and get the IIF register
 *
 *  c4x_get_iif     - obtains IIF register
 *  c4x_set_iif     - sets IIF register
 */

static inline unsigned int c4x_get_iif(void)
{
  register unsigned int _iif_value;

  __asm__( "ldi iif, %0" : "=r" (_iif_value) );
  return _iif_value;
}

static inline void c4x_set_iif(unsigned int _iif_value)
{
  __asm__( "ldi %0, iif" : : "g" (_iif_value) : "iif", "cc"); 
}

/*
 *  Routines to set and get the IIE register
 *
 *  c4x_get_iie     - obtains IIE register
 *  c4x_set_iie     - sets IIE register
 */

static inline unsigned int c4x_get_iie(void)
{
  register unsigned int _iie_value;

  __asm__( "ldi iie, %0" : "=r" (_iie_value) );
  return _iie_value;
}

static inline void c4x_set_iie(unsigned int _iie_value)
{
  __asm__( "ldi %0, iie" : : "g" (_iie_value) : "iie", "cc"); 
}

/*
 *  Routines to manipulates the mask portion of the IIE register.
 *
 *  c4x_ie_mask_all     - returns previous IIE mask
 *  c4x_ie_mask_restore - restores previous IIE mask
 *  c4x_ie_mask_flash   - temporarily restores previous IIE mask
 *  c4x_ie_mask_set     - sets a specific set of the IIE mask
 */

#if 0
#warning "C4x IIE masking routines not implemented."
#define c4x_iie_mask_all( _isr_cookie )
#define c4x_iie_mask_restore( _isr_cookie )
#define c4x_iie_mask_flash( _isr_cookie )
#define c4x_iie_mask_set( _new_mask )
#endif

#endif
/* end of C4x specific interrupt flag routines */

/*
 *  Routines to access the Interrupt Trap Table Pointer
 *
 *  c4x_get_ittp    - get ITTP
 *  c4x_set_ittp    - set ITTP
 */

static inline void * c4x_get_ittp(void)
{ 
  register unsigned int _if_value;
  
  __asm__( "ldi if, %0" : "=r" (_if_value) );
  return (void *)((_if_value & 0xffff0000) >> 8); 
}  

static inline void c4x_set_ittp(void *_ittp_value)
{  
  unsigned int _if_value;
  unsigned int _ittp_field;

#ifdef _TMS320C40
  _if_value = c4x_get_iif();
#else
  _if_value = c3x_get_if();
#endif
  _if_value &= 0xffff;
  _ittp_field = (((unsigned int) _ittp_value) >> 8);
  _if_value |= _ittp_field << 16 ;
#ifdef _TMS320C40
  c4x_set_iif( _if_value );
#else
  c3x_set_if( _if_value );
#endif
}  

#endif /* ifndef ASM */

#ifdef __cplusplus
}
#endif

#endif /* ! _INCLUDE_C4X_h */
/* end of include file */