source: rtems/cpukit/score/cpu/sparc/rtems/score/sparc.h @ 6a740c2

4.11
Last change on this file since 6a740c2 was 6a740c2, checked in by Daniel Hellstrom <daniel@…>, on May 23, 2014 at 1:52:16 PM

SPARC: add syscall 1 (exit) function entry point

The exit SPARC system call doesn't have a function entry
point like the others do. This is probably why people use
TA 0x0 instruction directly for shutting down the system.

  • Property mode set to 100644
File size: 9.8 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#define sparc_get_psr( _psr ) \
168  do { \
169     (_psr) = 0; \
170     __asm__ volatile( "rd %%psr, %0" :  "=r" (_psr) : "0" (_psr) ); \
171  } while ( 0 )
172
173/**
174 * @brief Macro to set the PSR.
175 *
176 * This macro sets the PSR register to the value in @a _psr.
177 */
178#define sparc_set_psr( _psr ) \
179  do { \
180    __asm__ volatile ( "mov  %0, %%psr " : "=r" ((_psr)) : "0" ((_psr)) ); \
181    nop(); \
182    nop(); \
183    nop(); \
184  } while ( 0 )
185
186/**
187 * @brief Macro to obtain the TBR.
188 *
189 * This macro returns the current contents of the TBR register in @a _tbr.
190 */
191#define sparc_get_tbr( _tbr ) \
192  do { \
193     (_tbr) = 0; /* to avoid unitialized warnings */ \
194     __asm__ volatile( "rd %%tbr, %0" :  "=r" (_tbr) : "0" (_tbr) ); \
195  } while ( 0 )
196
197/**
198 * @brief Macro to set the TBR.
199 *
200 * This macro sets the TBR register to the value in @a _tbr.
201 */
202#define sparc_set_tbr( _tbr ) \
203  do { \
204     __asm__ volatile( "wr %0, 0, %%tbr" :  "=r" (_tbr) : "0" (_tbr) ); \
205  } while ( 0 )
206
207/**
208 * @brief Macro to obtain the WIM.
209 *
210 * This macro returns the current contents of the WIM field in @a _wim.
211 */
212#define sparc_get_wim( _wim ) \
213  do { \
214    __asm__ volatile( "rd %%wim, %0" :  "=r" (_wim) : "0" (_wim) ); \
215  } while ( 0 )
216
217/**
218 * @brief Macro to set the WIM.
219 *
220 * This macro sets the WIM field to the value in @a _wim.
221 */
222#define sparc_set_wim( _wim ) \
223  do { \
224    __asm__ volatile( "wr %0, %%wim" :  "=r" (_wim) : "0" (_wim) ); \
225    nop(); \
226    nop(); \
227    nop(); \
228  } while ( 0 )
229
230/**
231 * @brief Macro to obtain the Y register.
232 *
233 * This macro returns the current contents of the Y register in @a _y.
234 */
235#define sparc_get_y( _y ) \
236  do { \
237    __asm__ volatile( "rd %%y, %0" :  "=r" (_y) : "0" (_y) ); \
238  } while ( 0 )
239
240/**
241 * @brief Macro to set the Y register.
242 *
243 * This macro sets the Y register to the value in @a _y.
244 */
245#define sparc_set_y( _y ) \
246  do { \
247    __asm__ volatile( "wr %0, %%y" :  "=r" (_y) : "0" (_y) ); \
248  } while ( 0 )
249
250/**
251 * @brief SPARC disable processor interrupts.
252 *
253 * This method is invoked to disable all maskable interrupts.
254 *
255 * @return This method returns the entire PSR contents.
256 */
257uint32_t sparc_disable_interrupts(void);
258
259/**
260 * @brief SPARC enable processor interrupts.
261 *
262 * This method is invoked to enable all maskable interrupts.
263 *
264 * @param[in] psr is the PSR returned by @ref sparc_disable_interrupts.
265 */
266void sparc_enable_interrupts(uint32_t psr);
267
268/**
269 * @brief SPARC exit through system call 1
270 *
271 * This method is invoked to go into system error halt. The optional
272 * arguments can be given to hypervisor, hardware debugger, simulator or
273 * similar.
274 *
275 * System error mode is entered when taking a trap when traps have been
276 * disabled. What happens when error mode is entered depends on the motherboard.
277 * In a typical development systems the CPU relingish control to the debugger,
278 * simulator, hypervisor or similar. The following steps are taken:
279 *
280 * 1. Going into system error mode by Software Trap 0
281 * 2. %g1=1 (syscall 1 - Exit)
282 * 3. %g2=Primary exit code
283 * 4. %g3=Secondary exit code. Dependends on %g2 exit type.
284 *
285 * This function never returns.
286 *
287 * @param[in] exitcode1 Primary exit code stored in CPU g2 register after exit
288 * @param[in] exitcode2 Primary exit code stored in CPU g3 register after exit
289 */
290void sparc_syscall_exit(uint32_t exitcode1, uint32_t exitcode2)
291  RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
292
293/**
294 * @brief SPARC flash processor interrupts.
295 *
296 * This method is invoked to temporarily enable all maskable interrupts.
297 *
298 * @param[in] _psr is the PSR returned by @ref sparc_disable_interrupts.
299 */
300#define sparc_flash_interrupts( _psr ) \
301  do { \
302    sparc_enable_interrupts( (_psr) ); \
303    _psr = sparc_disable_interrupts(); \
304  } while ( 0 )
305
306/**
307 * @brief SPARC obtain interrupt level.
308 *
309 * This method is invoked to obtain the current interrupt disable level.
310 *
311 * @param[in] _level is the PSR returned by @ref sparc_disable_interrupts.
312 */
313#define sparc_get_interrupt_level( _level ) \
314  do { \
315    register uint32_t   _psr_level = 0; \
316    \
317    sparc_get_psr( _psr_level ); \
318    (_level) = \
319      (_psr_level & SPARC_PSR_PIL_MASK) >> SPARC_PSR_PIL_BIT_POSITION; \
320  } while ( 0 )
321
322static inline uint32_t _LEON3_Get_current_processor( void )
323{
324  uint32_t asr17;
325
326  __asm__ volatile (
327    "rd %%asr17, %0"
328    : "=&r" (asr17)
329  );
330
331  return asr17 >> LEON3_ASR17_PROCESSOR_INDEX_SHIFT;
332}
333
334#endif
335
336#ifdef __cplusplus
337}
338#endif
339
340#endif /* _RTEMS_SCORE_SPARC_H */
Note: See TracBrowser for help on using the repository browser.