diff options
Diffstat (limited to 'include/rtems/score/sparc.h')
-rw-r--r-- | include/rtems/score/sparc.h | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/include/rtems/score/sparc.h b/include/rtems/score/sparc.h new file mode 100644 index 0000000000..ecac74de3c --- /dev/null +++ b/include/rtems/score/sparc.h @@ -0,0 +1,405 @@ +/** + * @file + * + * @brief Information Required to Build RTEMS for a Particular Member + * of the SPARC Family + * + * This file contains the information required to build + * RTEMS for a particular member of the SPARC family. It does + * this by setting variables to indicate which implementation + * dependent features are present in a particular member + * of the family. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * 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.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_SCORE_SPARC_H +#define _RTEMS_SCORE_SPARC_H + +#include <rtems/score/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * + * Currently recognized feature flags: + * + * + SPARC_HAS_FPU + * 0 - no HW FPU + * 1 - has HW FPU (assumed to be compatible w/90C602) + * + * + SPARC_HAS_BITSCAN + * 0 - does not have scan instructions + * 1 - has scan instruction (not currently implemented) + * + * + SPARC_NUMBER_OF_REGISTER_WINDOWS + * 8 is the most common number supported by SPARC implementations. + * SPARC_PSR_CWP_MASK is derived from this value. + */ + +/** + * Some higher end SPARCs have a bitscan instructions. It would + * be nice to take advantage of them. Right now, there is no + * port to a CPU model with this feature and no (untested) code + * that is based on this feature flag. + */ +#define SPARC_HAS_BITSCAN 0 + +/** + * This should be OK until a port to a higher end SPARC processor + * is made that has more than 8 register windows. If this cannot + * be determined based on multilib settings (v7/v8/v9), then the + * cpu_asm.S code that depends on this will have to move to libcpu. + */ +#define SPARC_NUMBER_OF_REGISTER_WINDOWS 8 + +/** + * This macro indicates whether this multilib variation has hardware + * floating point or not. We use the gcc cpp predefine _SOFT_FLOAT + * to determine that. + */ +#if defined(_SOFT_FLOAT) + #define SPARC_HAS_FPU 0 +#else + #define SPARC_HAS_FPU 1 +#endif + +/** + * This macro contains a string describing the multilib variant being + * build. + */ +#if SPARC_HAS_FPU + #define CPU_MODEL_NAME "w/FPU" +#else + #define CPU_MODEL_NAME "w/soft-float" +#endif + +/** + * Define the name of the CPU family. + */ +#define CPU_NAME "SPARC" + +/* + * Miscellaneous constants + */ + +/** + * PSR masks and starting bit positions + * + * NOTE: Reserved bits are ignored. + */ +#if (SPARC_NUMBER_OF_REGISTER_WINDOWS == 8) + #define SPARC_PSR_CWP_MASK 0x07 /* bits 0 - 4 */ +#elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 16) + #define SPARC_PSR_CWP_MASK 0x0F /* bits 0 - 4 */ +#elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 32) + #define SPARC_PSR_CWP_MASK 0x1F /* bits 0 - 4 */ +#else + #error "Unsupported number of register windows for this cpu" +#endif + +/** This constant is a mask for the ET bits in the PSR. */ +#define SPARC_PSR_ET_MASK 0x00000020 /* bit 5 */ +/** This constant is a mask for the PS bits in the PSR. */ +#define SPARC_PSR_PS_MASK 0x00000040 /* bit 6 */ +/** This constant is a mask for the S bits in the PSR. */ +#define SPARC_PSR_S_MASK 0x00000080 /* bit 7 */ +/** This constant is a mask for the PIL bits in the PSR. */ +#define SPARC_PSR_PIL_MASK 0x00000F00 /* bits 8 - 11 */ +/** This constant is a mask for the EF bits in the PSR. */ +#define SPARC_PSR_EF_MASK 0x00001000 /* bit 12 */ +/** This constant is a mask for the EC bits in the PSR. */ +#define SPARC_PSR_EC_MASK 0x00002000 /* bit 13 */ +/** This constant is a mask for the ICC bits in the PSR. */ +#define SPARC_PSR_ICC_MASK 0x00F00000 /* bits 20 - 23 */ +/** This constant is a mask for the VER bits in the PSR. */ +#define SPARC_PSR_VER_MASK 0x0F000000 /* bits 24 - 27 */ +/** This constant is a mask for the IMPL bits in the PSR. */ +#define SPARC_PSR_IMPL_MASK 0xF0000000 /* bits 28 - 31 */ + +/** This constant is the starting bit position of the CWP in the PSR. */ +#define SPARC_PSR_CWP_BIT_POSITION 0 /* bits 0 - 4 */ +/** This constant is the starting bit position of the ET in the PSR. */ +#define SPARC_PSR_ET_BIT_POSITION 5 /* bit 5 */ +/** This constant is the starting bit position of the PS in the PSR. */ +#define SPARC_PSR_PS_BIT_POSITION 6 /* bit 6 */ +/** This constant is the starting bit position of the S in the PSR. */ +#define SPARC_PSR_S_BIT_POSITION 7 /* bit 7 */ +/** This constant is the starting bit position of the PIL in the PSR. */ +#define SPARC_PSR_PIL_BIT_POSITION 8 /* bits 8 - 11 */ +/** This constant is the starting bit position of the EF in the PSR. */ +#define SPARC_PSR_EF_BIT_POSITION 12 /* bit 12 */ +/** This constant is the starting bit position of the EC in the PSR. */ +#define SPARC_PSR_EC_BIT_POSITION 13 /* bit 13 */ +/** This constant is the starting bit position of the ICC in the PSR. */ +#define SPARC_PSR_ICC_BIT_POSITION 20 /* bits 20 - 23 */ +/** This constant is the starting bit position of the VER in the PSR. */ +#define SPARC_PSR_VER_BIT_POSITION 24 /* bits 24 - 27 */ +/** This constant is the starting bit position of the IMPL in the PSR. */ +#define SPARC_PSR_IMPL_BIT_POSITION 28 /* bits 28 - 31 */ + +#define LEON3_ASR17_PROCESSOR_INDEX_SHIFT 28 + +/* SPARC Software Trap number definitions */ +#define SPARC_SWTRAP_SYSCALL 0 +#define SPARC_SWTRAP_IRQDIS 9 +#define SPARC_SWTRAP_IRQEN 10 + +#ifndef ASM + +/** + * This macro is a standard nop instruction. + */ +#define nop() \ + do { \ + __asm__ volatile ( "nop" ); \ + } while ( 0 ) + +/** + * @brief Macro to obtain the PSR. + * + * This macro returns the current contents of the PSR register in @a _psr. + */ +#if defined(RTEMS_PARAVIRT) + +uint32_t _SPARC_Get_PSR( void ); + +#define sparc_get_psr( _psr ) \ + (_psr) = _SPARC_Get_PSR() + +#else /* RTEMS_PARAVIRT */ + +#define sparc_get_psr( _psr ) \ + do { \ + (_psr) = 0; \ + __asm__ volatile( "rd %%psr, %0" : "=r" (_psr) : "0" (_psr) ); \ + } while ( 0 ) + +#endif /* RTEMS_PARAVIRT */ + +/** + * @brief Macro to set the PSR. + * + * This macro sets the PSR register to the value in @a _psr. + */ +#if defined(RTEMS_PARAVIRT) + +void _SPARC_Set_PSR( uint32_t new_psr ); + +#define sparc_set_psr( _psr ) \ + _SPARC_Set_PSR( _psr ) + +#else /* RTEMS_PARAVIRT */ + +#define sparc_set_psr( _psr ) \ + do { \ + __asm__ volatile ( "mov %0, %%psr " : "=r" ((_psr)) : "0" ((_psr)) ); \ + nop(); \ + nop(); \ + nop(); \ + } while ( 0 ) + +#endif /* RTEMS_PARAVIRT */ + +/** + * @brief Macro to obtain the TBR. + * + * This macro returns the current contents of the TBR register in @a _tbr. + */ +#if defined(RTEMS_PARAVIRT) + +uint32_t _SPARC_Get_TBR( void ); + +#define sparc_get_tbr( _tbr ) \ + (_tbr) = _SPARC_Get_TBR() + +#else /* RTEMS_PARAVIRT */ + +#define sparc_get_tbr( _tbr ) \ + do { \ + (_tbr) = 0; /* to avoid unitialized warnings */ \ + __asm__ volatile( "rd %%tbr, %0" : "=r" (_tbr) : "0" (_tbr) ); \ + } while ( 0 ) + +#endif /* RTEMS_PARAVIRT */ + +/** + * @brief Macro to set the TBR. + * + * This macro sets the TBR register to the value in @a _tbr. + */ +#if defined(RTEMS_PARAVIRT) + +void _SPARC_Set_TBR( uint32_t new_tbr ); + +#define sparc_set_tbr( _tbr ) \ + _SPARC_Set_TBR((_tbr)) + +#else /* RTEMS_PARAVIRT */ + +#define sparc_set_tbr( _tbr ) \ + do { \ + __asm__ volatile( "wr %0, 0, %%tbr" : "=r" (_tbr) : "0" (_tbr) ); \ + } while ( 0 ) + +#endif /* RTEMS_PARAVIRT */ + +/** + * @brief Macro to obtain the WIM. + * + * This macro returns the current contents of the WIM field in @a _wim. + */ +#define sparc_get_wim( _wim ) \ + do { \ + __asm__ volatile( "rd %%wim, %0" : "=r" (_wim) : "0" (_wim) ); \ + } while ( 0 ) + +/** + * @brief Macro to set the WIM. + * + * This macro sets the WIM field to the value in @a _wim. + */ +#define sparc_set_wim( _wim ) \ + do { \ + __asm__ volatile( "wr %0, %%wim" : "=r" (_wim) : "0" (_wim) ); \ + nop(); \ + nop(); \ + nop(); \ + } while ( 0 ) + +/** + * @brief Macro to obtain the Y register. + * + * This macro returns the current contents of the Y register in @a _y. + */ +#define sparc_get_y( _y ) \ + do { \ + __asm__ volatile( "rd %%y, %0" : "=r" (_y) : "0" (_y) ); \ + } while ( 0 ) + +/** + * @brief Macro to set the Y register. + * + * This macro sets the Y register to the value in @a _y. + */ +#define sparc_set_y( _y ) \ + do { \ + __asm__ volatile( "wr %0, %%y" : "=r" (_y) : "0" (_y) ); \ + } while ( 0 ) + +/** + * @brief SPARC disable processor interrupts. + * + * This method is invoked to disable all maskable interrupts. + * + * @return This method returns the entire PSR contents. + */ +static inline uint32_t sparc_disable_interrupts(void) +{ + register uint32_t psr __asm__("g1"); /* return value of trap handler */ + __asm__ volatile ( "ta %1\n\t" : "=r" (psr) : "i" (SPARC_SWTRAP_IRQDIS)); + return psr; +} + +/** + * @brief SPARC enable processor interrupts. + * + * This method is invoked to enable all maskable interrupts. + * + * @param[in] psr is the PSR returned by @ref sparc_disable_interrupts. + */ +static inline void sparc_enable_interrupts(uint32_t psr) +{ + register uint32_t _psr __asm__("g1") = psr; /* input to trap handler */ + + /* + * The trap instruction has a higher trap priority than the interrupts + * according to "The SPARC Architecture Manual: Version 8", Table 7-1 + * "Exception and Interrupt Request Priority and tt Values". Add a nop to + * prevent a trap instruction right after the interrupt enable trap. + */ + __asm__ volatile ( "ta %0\nnop\n" :: "i" (SPARC_SWTRAP_IRQEN), "r" (_psr)); +} + +/** + * @brief SPARC exit through system call 1 + * + * This method is invoked to go into system error halt. The optional + * arguments can be given to hypervisor, hardware debugger, simulator or + * similar. + * + * System error mode is entered when taking a trap when traps have been + * disabled. What happens when error mode is entered depends on the motherboard. + * In a typical development systems the CPU relingish control to the debugger, + * simulator, hypervisor or similar. The following steps are taken: + * + * 1. Going into system error mode by Software Trap 0 + * 2. %g1=1 (syscall 1 - Exit) + * 3. %g2=Primary exit code + * 4. %g3=Secondary exit code. Dependends on %g2 exit type. + * + * This function never returns. + * + * @param[in] exitcode1 Primary exit code stored in CPU g2 register after exit + * @param[in] exitcode2 Primary exit code stored in CPU g3 register after exit + */ +void sparc_syscall_exit(uint32_t exitcode1, uint32_t exitcode2) + RTEMS_NO_RETURN; + +/** + * @brief SPARC flash processor interrupts. + * + * This method is invoked to temporarily enable all maskable interrupts. + * + * @param[in] _psr is the PSR returned by @ref sparc_disable_interrupts. + */ +#define sparc_flash_interrupts( _psr ) \ + do { \ + sparc_enable_interrupts( (_psr) ); \ + _psr = sparc_disable_interrupts(); \ + } while ( 0 ) + +/** + * @brief SPARC obtain interrupt level. + * + * This method is invoked to obtain the current interrupt disable level. + * + * @param[in] _level is the PSR returned by @ref sparc_disable_interrupts. + */ +#define sparc_get_interrupt_level( _level ) \ + do { \ + register uint32_t _psr_level = 0; \ + \ + sparc_get_psr( _psr_level ); \ + (_level) = \ + (_psr_level & SPARC_PSR_PIL_MASK) >> SPARC_PSR_PIL_BIT_POSITION; \ + } while ( 0 ) + +static inline uint32_t _LEON3_Get_current_processor( void ) +{ + uint32_t asr17; + + __asm__ volatile ( + "rd %%asr17, %0" + : "=&r" (asr17) + ); + + return asr17 >> LEON3_ASR17_PROCESSOR_INDEX_SHIFT; +} + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _RTEMS_SCORE_SPARC_H */ |