RTEMS  5.1
sparc.h
Go to the documentation of this file.
1 
14 /*
15  * COPYRIGHT (c) 1989-2011.
16  * On-Line Applications Research Corporation (OAR).
17  *
18  * The license and distribution terms for this file may be
19  * found in the file LICENSE in this distribution or at
20  * http://www.rtems.org/license/LICENSE.
21  */
22 
23 #ifndef _RTEMS_SCORE_SPARC_H
24 #define _RTEMS_SCORE_SPARC_H
25 
26 #include <rtems/score/basedefs.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /*
33  *
34  * Currently recognized feature flags:
35  *
36  * + SPARC_HAS_FPU
37  * 0 - no HW FPU
38  * 1 - has HW FPU (assumed to be compatible w/90C602)
39  *
40  * + SPARC_HAS_BITSCAN
41  * 0 - does not have scan instructions
42  * 1 - has scan instruction (not currently implemented)
43  *
44  * + SPARC_NUMBER_OF_REGISTER_WINDOWS
45  * 8 is the most common number supported by SPARC implementations.
46  * SPARC_PSR_CWP_MASK is derived from this value.
47  */
48 
55 #define SPARC_HAS_BITSCAN 0
56 
63 #define SPARC_NUMBER_OF_REGISTER_WINDOWS 8
64 
69 #if defined(__FIX_LEON3FT_B2BST)
70  #define SPARC_LEON3FT_B2BST_NOP nop
71 #else
72  #define SPARC_LEON3FT_B2BST_NOP
73 #endif
74 
80 #if defined(_SOFT_FLOAT)
81  #define SPARC_HAS_FPU 0
82 #else
83  #define SPARC_HAS_FPU 1
84 #endif
85 
90 #if SPARC_HAS_FPU
91  #define CPU_MODEL_NAME "w/FPU"
92 #else
93  #define CPU_MODEL_NAME "w/soft-float"
94 #endif
95 
99 #define CPU_NAME "SPARC"
100 
101 /*
102  * Miscellaneous constants
103  */
104 
110 #if (SPARC_NUMBER_OF_REGISTER_WINDOWS == 8)
111  #define SPARC_PSR_CWP_MASK 0x07 /* bits 0 - 4 */
112 #elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 16)
113  #define SPARC_PSR_CWP_MASK 0x0F /* bits 0 - 4 */
114 #elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 32)
115  #define SPARC_PSR_CWP_MASK 0x1F /* bits 0 - 4 */
116 #else
117  #error "Unsupported number of register windows for this cpu"
118 #endif
119 
121 #define SPARC_PSR_ET_MASK 0x00000020 /* bit 5 */
122 
123 #define SPARC_PSR_PS_MASK 0x00000040 /* bit 6 */
124 
125 #define SPARC_PSR_S_MASK 0x00000080 /* bit 7 */
126 
127 #define SPARC_PSR_PIL_MASK 0x00000F00 /* bits 8 - 11 */
128 
129 #define SPARC_PSR_EF_MASK 0x00001000 /* bit 12 */
130 
131 #define SPARC_PSR_EC_MASK 0x00002000 /* bit 13 */
132 
133 #define SPARC_PSR_ICC_MASK 0x00F00000 /* bits 20 - 23 */
134 
135 #define SPARC_PSR_VER_MASK 0x0F000000 /* bits 24 - 27 */
136 
137 #define SPARC_PSR_IMPL_MASK 0xF0000000 /* bits 28 - 31 */
138 
140 #define SPARC_PSR_CWP_BIT_POSITION 0 /* bits 0 - 4 */
141 
142 #define SPARC_PSR_ET_BIT_POSITION 5 /* bit 5 */
143 
144 #define SPARC_PSR_PS_BIT_POSITION 6 /* bit 6 */
145 
146 #define SPARC_PSR_S_BIT_POSITION 7 /* bit 7 */
147 
148 #define SPARC_PSR_PIL_BIT_POSITION 8 /* bits 8 - 11 */
149 
150 #define SPARC_PSR_EF_BIT_POSITION 12 /* bit 12 */
151 
152 #define SPARC_PSR_EC_BIT_POSITION 13 /* bit 13 */
153 
154 #define SPARC_PSR_ICC_BIT_POSITION 20 /* bits 20 - 23 */
155 
156 #define SPARC_PSR_VER_BIT_POSITION 24 /* bits 24 - 27 */
157 
158 #define SPARC_PSR_IMPL_BIT_POSITION 28 /* bits 28 - 31 */
159 
160 #define LEON3_ASR17_PROCESSOR_INDEX_SHIFT 28
161 
162 /* SPARC Software Trap number definitions */
163 #define SPARC_SWTRAP_SYSCALL 0
164 #define SPARC_SWTRAP_IRQDIS 9
165 #define SPARC_SWTRAP_IRQEN 10
166 #if SPARC_HAS_FPU == 1
167 #define SPARC_SWTRAP_IRQDIS_FP 11
168 #endif
169 
170 #ifndef ASM
171 
175 #define nop() \
176  do { \
177  __asm__ volatile ( "nop" ); \
178  } while ( 0 )
179 
185 #if defined(RTEMS_PARAVIRT)
186 
187 uint32_t _SPARC_Get_PSR( void );
188 
189 #define sparc_get_psr( _psr ) \
190  (_psr) = _SPARC_Get_PSR()
191 
192 #else /* RTEMS_PARAVIRT */
193 
194 #define sparc_get_psr( _psr ) \
195  do { \
196  (_psr) = 0; \
197  __asm__ volatile( "rd %%psr, %0" : "=r" (_psr) : "0" (_psr) ); \
198  } while ( 0 )
199 
200 #endif /* RTEMS_PARAVIRT */
201 
207 #if defined(RTEMS_PARAVIRT)
208 
209 void _SPARC_Set_PSR( uint32_t new_psr );
210 
211 #define sparc_set_psr( _psr ) \
212  _SPARC_Set_PSR( _psr )
213 
214 #else /* RTEMS_PARAVIRT */
215 
216 #define sparc_set_psr( _psr ) \
217  do { \
218  __asm__ volatile ( "mov %0, %%psr " : "=r" ((_psr)) : "0" ((_psr)) ); \
219  nop(); \
220  nop(); \
221  nop(); \
222  } while ( 0 )
223 
224 #endif /* RTEMS_PARAVIRT */
225 
231 #if defined(RTEMS_PARAVIRT)
232 
233 uint32_t _SPARC_Get_TBR( void );
234 
235 #define sparc_get_tbr( _tbr ) \
236  (_tbr) = _SPARC_Get_TBR()
237 
238 #else /* RTEMS_PARAVIRT */
239 
240 #define sparc_get_tbr( _tbr ) \
241  do { \
242  (_tbr) = 0; /* to avoid unitialized warnings */ \
243  __asm__ volatile( "rd %%tbr, %0" : "=r" (_tbr) : "0" (_tbr) ); \
244  } while ( 0 )
245 
246 #endif /* RTEMS_PARAVIRT */
247 
253 #if defined(RTEMS_PARAVIRT)
254 
255 void _SPARC_Set_TBR( uint32_t new_tbr );
256 
257 #define sparc_set_tbr( _tbr ) \
258  _SPARC_Set_TBR((_tbr))
259 
260 #else /* RTEMS_PARAVIRT */
261 
262 #define sparc_set_tbr( _tbr ) \
263  do { \
264  __asm__ volatile( "wr %0, 0, %%tbr" : "=r" (_tbr) : "0" (_tbr) ); \
265  } while ( 0 )
266 
267 #endif /* RTEMS_PARAVIRT */
268 
274 #define sparc_get_wim( _wim ) \
275  do { \
276  __asm__ volatile( "rd %%wim, %0" : "=r" (_wim) : "0" (_wim) ); \
277  } while ( 0 )
278 
284 #define sparc_set_wim( _wim ) \
285  do { \
286  __asm__ volatile( "wr %0, %%wim" : "=r" (_wim) : "0" (_wim) ); \
287  nop(); \
288  nop(); \
289  nop(); \
290  } while ( 0 )
291 
297 #define sparc_get_y( _y ) \
298  do { \
299  __asm__ volatile( "rd %%y, %0" : "=r" (_y) : "0" (_y) ); \
300  } while ( 0 )
301 
307 #define sparc_set_y( _y ) \
308  do { \
309  __asm__ volatile( "wr %0, %%y" : "=r" (_y) : "0" (_y) ); \
310  } while ( 0 )
311 
319 static inline uint32_t sparc_disable_interrupts(void)
320 {
321  register uint32_t psr __asm__("g1"); /* return value of trap handler */
322  __asm__ volatile ( "ta %1\n\t" : "=r" (psr) : "i" (SPARC_SWTRAP_IRQDIS));
323  return psr;
324 }
325 
333 static inline void sparc_enable_interrupts(uint32_t psr)
334 {
335  register uint32_t _psr __asm__("g1") = psr; /* input to trap handler */
336 
337  /*
338  * The trap instruction has a higher trap priority than the interrupts
339  * according to "The SPARC Architecture Manual: Version 8", Table 7-1
340  * "Exception and Interrupt Request Priority and tt Values". Add a nop to
341  * prevent a trap instruction right after the interrupt enable trap.
342  */
343  __asm__ volatile ( "ta %0\nnop\n" :: "i" (SPARC_SWTRAP_IRQEN), "r" (_psr));
344 }
345 
368 void sparc_syscall_exit(uint32_t exitcode1, uint32_t exitcode2)
370 
378 #define sparc_flash_interrupts( _psr ) \
379  do { \
380  sparc_enable_interrupts( (_psr) ); \
381  _psr = sparc_disable_interrupts(); \
382  } while ( 0 )
383 
391 #define sparc_get_interrupt_level( _level ) \
392  do { \
393  uint32_t _psr_level = 0; \
394  \
395  sparc_get_psr( _psr_level ); \
396  (_level) = \
397  (_psr_level & SPARC_PSR_PIL_MASK) >> SPARC_PSR_PIL_BIT_POSITION; \
398  } while ( 0 )
399 
400 static inline uint32_t _LEON3_Get_current_processor( void )
401 {
402  uint32_t asr17;
403 
404  __asm__ volatile (
405  "rd %%asr17, %0"
406  : "=&r" (asr17)
407  );
408 
409  return asr17 >> LEON3_ASR17_PROCESSOR_INDEX_SHIFT;
410 }
411 
412 #endif
413 
414 #ifdef __cplusplus
415 }
416 #endif
417 
418 #endif /* _RTEMS_SCORE_SPARC_H */
#define RTEMS_NO_RETURN
Definition: basedefs.h:102
void sparc_syscall_exit(uint32_t exitcode1, uint32_t exitcode2) RTEMS_NO_RETURN
SPARC exit through system call 1.
register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__("g6")
The pointer to the current per-CPU control is available via register g6.
Basic Definitions.