diff options
Diffstat (limited to 'cpukit/score/cpu/c4x/rtems/score/c4x.h')
-rw-r--r-- | cpukit/score/cpu/c4x/rtems/score/c4x.h | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/cpukit/score/cpu/c4x/rtems/score/c4x.h b/cpukit/score/cpu/c4x/rtems/score/c4x.h new file mode 100644 index 0000000000..fe1d2cd139 --- /dev/null +++ b/cpukit/score/cpu/c4x/rtems/score/c4x.h @@ -0,0 +1,362 @@ +/* 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 & 0xffff) >> 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; +#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 */ |