summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/c4x/rtems/score/c4x.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/cpu/c4x/rtems/score/c4x.h')
-rw-r--r--cpukit/score/cpu/c4x/rtems/score/c4x.h362
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 */