source: rtems/cpukit/score/cpu/sparc/rtems/score/sparc.h @ 8df1f408

4.11
Last change on this file since 8df1f408 was 8df1f408, checked in by Christian Mauderer <Christian.Mauderer@…>, on Jun 2, 2014 at 2:31:51 PM

score/sparc: Add support for paravirtualization

Guest systems in paravirtualization environments run usually in user
mode. Thus it is not possible to directly access the PSR and TBR
registers. Use functions instead of inline assembler to access these
registers if RTEMS_PARAVIRT is defined.

  • Property mode set to 100644
File size: 10.5 KB
Line 
1/**
2 * @file
3 *
4 * @brief Information Required to Build RTEMS for a Particular Member
5 * of the SPARC Family
6 *
7 * This file contains the information required to build
8 * RTEMS for a particular member of the SPARC family.  It does
9 * this by setting variables to indicate which implementation
10 * dependent features are present in a particular member
11 * of the family.
12 */
13
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/types.h>
27
28#ifdef __cplusplus
29extern "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
49/**
50 * Some higher end SPARCs have a bitscan instructions. It would
51 * be nice to take advantage of them.  Right now, there is no
52 * port to a CPU model with this feature and no (untested) code
53 * that is based on this feature flag.
54 */
55#define SPARC_HAS_BITSCAN                0
56
57/**
58 * This should be OK until a port to a higher end SPARC processor
59 * is made that has more than 8 register windows.  If this cannot
60 * be determined based on multilib settings (v7/v8/v9), then the
61 * cpu_asm.S code that depends on this will have to move to libcpu.
62 */
63#define SPARC_NUMBER_OF_REGISTER_WINDOWS 8
64
65/**
66 * This macro indicates whether this multilib variation has hardware
67 * floating point or not.  We use the gcc cpp predefine _SOFT_FLOAT
68 * to determine that.
69 */
70#if defined(_SOFT_FLOAT)
71  #define SPARC_HAS_FPU 0
72#else
73  #define SPARC_HAS_FPU 1
74#endif
75
76/**
77 * This macro contains a string describing the multilib variant being
78 * build.
79 */
80#if SPARC_HAS_FPU
81  #define CPU_MODEL_NAME "w/FPU"
82#else
83  #define CPU_MODEL_NAME "w/soft-float"
84#endif
85
86/**
87 * Define the name of the CPU family.
88 */
89#define CPU_NAME "SPARC"
90
91/*
92 *  Miscellaneous constants
93 */
94
95/**
96 * PSR masks and starting bit positions
97 *
98 * NOTE: Reserved bits are ignored.
99 */
100#if (SPARC_NUMBER_OF_REGISTER_WINDOWS == 8)
101  #define SPARC_PSR_CWP_MASK               0x07   /* bits  0 -  4 */
102#elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 16)
103  #define SPARC_PSR_CWP_MASK               0x0F   /* bits  0 -  4 */
104#elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 32)
105  #define SPARC_PSR_CWP_MASK               0x1F   /* bits  0 -  4 */
106#else
107  #error "Unsupported number of register windows for this cpu"
108#endif
109
110/** This constant is a mask for the ET bits in the PSR. */
111#define SPARC_PSR_ET_MASK   0x00000020   /* bit   5 */
112/** This constant is a mask for the PS bits in the PSR. */
113#define SPARC_PSR_PS_MASK   0x00000040   /* bit   6 */
114/** This constant is a mask for the S bits in the PSR. */
115#define SPARC_PSR_S_MASK    0x00000080   /* bit   7 */
116/** This constant is a mask for the PIL bits in the PSR. */
117#define SPARC_PSR_PIL_MASK  0x00000F00   /* bits  8 - 11 */
118/** This constant is a mask for the EF bits in the PSR. */
119#define SPARC_PSR_EF_MASK   0x00001000   /* bit  12 */
120/** This constant is a mask for the EC bits in the PSR. */
121#define SPARC_PSR_EC_MASK   0x00002000   /* bit  13 */
122/** This constant is a mask for the ICC bits in the PSR. */
123#define SPARC_PSR_ICC_MASK  0x00F00000   /* bits 20 - 23 */
124/** This constant is a mask for the VER bits in the PSR. */
125#define SPARC_PSR_VER_MASK  0x0F000000   /* bits 24 - 27 */
126/** This constant is a mask for the IMPL bits in the PSR. */
127#define SPARC_PSR_IMPL_MASK 0xF0000000   /* bits 28 - 31 */
128
129/** This constant is the starting bit position of the CWP in the PSR. */
130#define SPARC_PSR_CWP_BIT_POSITION   0   /* bits  0 -  4 */
131/** This constant is the starting bit position of the ET in the PSR. */
132#define SPARC_PSR_ET_BIT_POSITION    5   /* bit   5 */
133/** This constant is the starting bit position of the PS in the PSR. */
134#define SPARC_PSR_PS_BIT_POSITION    6   /* bit   6 */
135/** This constant is the starting bit position of the S in the PSR. */
136#define SPARC_PSR_S_BIT_POSITION     7   /* bit   7 */
137/** This constant is the starting bit position of the PIL in the PSR. */
138#define SPARC_PSR_PIL_BIT_POSITION   8   /* bits  8 - 11 */
139/** This constant is the starting bit position of the EF in the PSR. */
140#define SPARC_PSR_EF_BIT_POSITION   12   /* bit  12 */
141/** This constant is the starting bit position of the EC in the PSR. */
142#define SPARC_PSR_EC_BIT_POSITION   13   /* bit  13 */
143/** This constant is the starting bit position of the ICC in the PSR. */
144#define SPARC_PSR_ICC_BIT_POSITION  20   /* bits 20 - 23 */
145/** This constant is the starting bit position of the VER in the PSR. */
146#define SPARC_PSR_VER_BIT_POSITION  24   /* bits 24 - 27 */
147/** This constant is the starting bit position of the IMPL in the PSR. */
148#define SPARC_PSR_IMPL_BIT_POSITION 28   /* bits 28 - 31 */
149
150#define LEON3_ASR17_PROCESSOR_INDEX_SHIFT 28
151
152#ifndef ASM
153
154/**
155 * This macro is a standard nop instruction.
156 */
157#define nop() \
158  do { \
159    __asm__ volatile ( "nop" ); \
160  } while ( 0 )
161
162/**
163 * @brief Macro to obtain the PSR.
164 *
165 * This macro returns the current contents of the PSR register in @a _psr.
166 */
167#if defined(RTEMS_PARAVIRT)
168
169uint32_t _SPARC_Get_PSR( void );
170
171#define sparc_get_psr( _psr ) \
172  (_psr) = _SPARC_Get_PSR()
173
174#else /* RTEMS_PARAVIRT */
175
176#define sparc_get_psr( _psr ) \
177  do { \
178     (_psr) = 0; \
179     __asm__ volatile( "rd %%psr, %0" :  "=r" (_psr) : "0" (_psr) ); \
180  } while ( 0 )
181
182#endif /* RTEMS_PARAVIRT */
183
184/**
185 * @brief Macro to set the PSR.
186 *
187 * This macro sets the PSR register to the value in @a _psr.
188 */
189#if defined(RTEMS_PARAVIRT)
190
191void _SPARC_Set_PSR( uint32_t new_psr );
192
193#define sparc_set_psr( _psr ) \
194  _SPARC_Set_PSR( _psr )
195
196#else /* RTEMS_PARAVIRT */
197
198#define sparc_set_psr( _psr ) \
199  do { \
200    __asm__ volatile ( "mov  %0, %%psr " : "=r" ((_psr)) : "0" ((_psr)) ); \
201    nop(); \
202    nop(); \
203    nop(); \
204  } while ( 0 )
205
206#endif /* RTEMS_PARAVIRT */
207
208/**
209 * @brief Macro to obtain the TBR.
210 *
211 * This macro returns the current contents of the TBR register in @a _tbr.
212 */
213#if defined(RTEMS_PARAVIRT)
214
215uint32_t _SPARC_Get_TBR( void );
216
217#define sparc_get_tbr( _tbr ) \
218  (_tbr) = _SPARC_Get_TBR()
219
220#else /* RTEMS_PARAVIRT */
221
222#define sparc_get_tbr( _tbr ) \
223  do { \
224     (_tbr) = 0; /* to avoid unitialized warnings */ \
225     __asm__ volatile( "rd %%tbr, %0" :  "=r" (_tbr) : "0" (_tbr) ); \
226  } while ( 0 )
227
228#endif /* RTEMS_PARAVIRT */
229
230/**
231 * @brief Macro to set the TBR.
232 *
233 * This macro sets the TBR register to the value in @a _tbr.
234 */
235#if defined(RTEMS_PARAVIRT)
236
237void _SPARC_Set_TBR( uint32_t new_tbr );
238
239#define sparc_set_tbr( _tbr ) \
240  _SPARC_Set_TBR((_tbr))
241
242#else /* RTEMS_PARAVIRT */
243
244#define sparc_set_tbr( _tbr ) \
245  do { \
246     __asm__ volatile( "wr %0, 0, %%tbr" :  "=r" (_tbr) : "0" (_tbr) ); \
247  } while ( 0 )
248
249#endif /* RTEMS_PARAVIRT */
250
251/**
252 * @brief Macro to obtain the WIM.
253 *
254 * This macro returns the current contents of the WIM field in @a _wim.
255 */
256#define sparc_get_wim( _wim ) \
257  do { \
258    __asm__ volatile( "rd %%wim, %0" :  "=r" (_wim) : "0" (_wim) ); \
259  } while ( 0 )
260
261/**
262 * @brief Macro to set the WIM.
263 *
264 * This macro sets the WIM field to the value in @a _wim.
265 */
266#define sparc_set_wim( _wim ) \
267  do { \
268    __asm__ volatile( "wr %0, %%wim" :  "=r" (_wim) : "0" (_wim) ); \
269    nop(); \
270    nop(); \
271    nop(); \
272  } while ( 0 )
273
274/**
275 * @brief Macro to obtain the Y register.
276 *
277 * This macro returns the current contents of the Y register in @a _y.
278 */
279#define sparc_get_y( _y ) \
280  do { \
281    __asm__ volatile( "rd %%y, %0" :  "=r" (_y) : "0" (_y) ); \
282  } while ( 0 )
283
284/**
285 * @brief Macro to set the Y register.
286 *
287 * This macro sets the Y register to the value in @a _y.
288 */
289#define sparc_set_y( _y ) \
290  do { \
291    __asm__ volatile( "wr %0, %%y" :  "=r" (_y) : "0" (_y) ); \
292  } while ( 0 )
293
294/**
295 * @brief SPARC disable processor interrupts.
296 *
297 * This method is invoked to disable all maskable interrupts.
298 *
299 * @return This method returns the entire PSR contents.
300 */
301uint32_t sparc_disable_interrupts(void);
302
303/**
304 * @brief SPARC enable processor interrupts.
305 *
306 * This method is invoked to enable all maskable interrupts.
307 *
308 * @param[in] psr is the PSR returned by @ref sparc_disable_interrupts.
309 */
310void sparc_enable_interrupts(uint32_t psr);
311
312/**
313 * @brief SPARC exit through system call 1
314 *
315 * This method is invoked to go into system error halt. The optional
316 * arguments can be given to hypervisor, hardware debugger, simulator or
317 * similar.
318 *
319 * System error mode is entered when taking a trap when traps have been
320 * disabled. What happens when error mode is entered depends on the motherboard.
321 * In a typical development systems the CPU relingish control to the debugger,
322 * simulator, hypervisor or similar. The following steps are taken:
323 *
324 * 1. Going into system error mode by Software Trap 0
325 * 2. %g1=1 (syscall 1 - Exit)
326 * 3. %g2=Primary exit code
327 * 4. %g3=Secondary exit code. Dependends on %g2 exit type.
328 *
329 * This function never returns.
330 *
331 * @param[in] exitcode1 Primary exit code stored in CPU g2 register after exit
332 * @param[in] exitcode2 Primary exit code stored in CPU g3 register after exit
333 */
334void sparc_syscall_exit(uint32_t exitcode1, uint32_t exitcode2)
335  RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
336
337/**
338 * @brief SPARC flash processor interrupts.
339 *
340 * This method is invoked to temporarily enable all maskable interrupts.
341 *
342 * @param[in] _psr is the PSR returned by @ref sparc_disable_interrupts.
343 */
344#define sparc_flash_interrupts( _psr ) \
345  do { \
346    sparc_enable_interrupts( (_psr) ); \
347    _psr = sparc_disable_interrupts(); \
348  } while ( 0 )
349
350/**
351 * @brief SPARC obtain interrupt level.
352 *
353 * This method is invoked to obtain the current interrupt disable level.
354 *
355 * @param[in] _level is the PSR returned by @ref sparc_disable_interrupts.
356 */
357#define sparc_get_interrupt_level( _level ) \
358  do { \
359    register uint32_t   _psr_level = 0; \
360    \
361    sparc_get_psr( _psr_level ); \
362    (_level) = \
363      (_psr_level & SPARC_PSR_PIL_MASK) >> SPARC_PSR_PIL_BIT_POSITION; \
364  } while ( 0 )
365
366static inline uint32_t _LEON3_Get_current_processor( void )
367{
368  uint32_t asr17;
369
370  __asm__ volatile (
371    "rd %%asr17, %0"
372    : "=&r" (asr17)
373  );
374
375  return asr17 >> LEON3_ASR17_PROCESSOR_INDEX_SHIFT;
376}
377
378#endif
379
380#ifdef __cplusplus
381}
382#endif
383
384#endif /* _RTEMS_SCORE_SPARC_H */
Note: See TracBrowser for help on using the repository browser.