RTEMS  5.0.0
sparc64.h
Go to the documentation of this file.
1 
11 /*
12  * COPYRIGHT (c) 1989-1999. On-Line Applications Research Corporation (OAR).
13  *
14  * This file is based on the SPARC sparc.h file. Modifications are made
15  * to support the SPARC64 processor.
16  * COPYRIGHT (c) 2010. Gedare Bloom.
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 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 /*
31  * This file contains the information required to build
32  * RTEMS for a particular member of the "sparc" family. It does
33  * this by setting variables to indicate which implementation
34  * dependent features are present in a particular member
35  * of the family.
36  *
37  * Currently recognized feature flags:
38  *
39  * + SPARC_HAS_FPU
40  * 0 - no HW FPU
41  * 1 - has HW FPU (assumed to be compatible w/90C602)
42  *
43  * + SPARC_HAS_BITSCAN
44  * 0 - does not have scan instructions
45  * 1 - has scan instruction (not currently implemented)
46  *
47  * + SPARC_NUMBER_OF_REGISTER_WINDOWS
48  * 8 is the most common number supported by SPARC implementations.
49  * SPARC_PSR_CWP_MASK is derived from this value.
50  */
51 
52 /*
53  * Some higher end SPARCs have a bitscan instructions. It would
54  * be nice to take advantage of them. Right now, there is no
55  * port to a CPU model with this feature and no (untested) code
56  * that is based on this feature flag.
57  */
58 
59 #define SPARC_HAS_BITSCAN 0
60 
61 /*
62  * This should be OK until a port to a higher end SPARC processor
63  * is made that has more than 8 register windows. If this cannot
64  * be determined based on multilib settings (v7/v8/v9), then the
65  * cpu_asm.S code that depends on this will have to move to libcpu.
66  *
67  * SPARC v9 supports from 3 to 32 register windows.
68  * N_REG_WINDOWS = 8 on UltraSPARC T1 (impl. dep. #2-V8).
69  */
70 
71 #define SPARC_NUMBER_OF_REGISTER_WINDOWS 8
72 
73 /*
74  * This should be determined based on some soft float derived
75  * cpp predefine but gcc does not currently give us that information.
76  */
77 
78 
79 #if defined(_SOFT_FLOAT)
80 #define SPARC_HAS_FPU 0
81 #else
82 #define SPARC_HAS_FPU 1
83 #endif
84 
85 #if SPARC_HAS_FPU
86 #define CPU_MODEL_NAME "w/FPU"
87 #else
88 #define CPU_MODEL_NAME "w/soft-float"
89 #endif
90 
91 /*
92  * Define the name of the CPU family.
93  */
94 
95 #define CPU_NAME "SPARC"
96 
97 /*
98  * Miscellaneous constants
99  */
100 
101 /*
102  * The PSR is deprecated and deleted.
103  *
104  * The following registers represent fields of the PSR:
105  * PIL - Processor Interrupt Level register
106  * CWP - Current Window Pointer register
107  * VER - Version register
108  * CCR - Condition Codes Register
109  * PSTATE - Processor State register
110  */
111 
112 /*
113  * PSTATE masks and starting bit positions
114  *
115  * NOTE: Reserved bits are ignored.
116  */
117 
118 #define SPARC_PSTATE_AG_MASK 0x00000001 /* bit 0 */
119 #define SPARC_PSTATE_IE_MASK 0x00000002 /* bit 1 */
120 #define SPARC_PSTATE_PRIV_MASK 0x00000004 /* bit 2 */
121 #define SPARC_PSTATE_AM_MASK 0x00000008 /* bit 3 */
122 #define SPARC_PSTATE_PEF_MASK 0x00000010 /* bit 4 */
123 #define SPARC_PSTATE_MM_MASK 0x00000040 /* bit 6 */
124 #define SPARC_PSTATE_TLE_MASK 0x00000100 /* bit 8 */
125 #define SPARC_PSTATE_CLE_MASK 0x00000200 /* bit 9 */
126 
127 #define SPARC_PSTATE_AG_BIT_POSITION 0 /* bit 0 */
128 #define SPARC_PSTATE_IE_BIT_POSITION 1 /* bit 1 */
129 #define SPARC_PSTATE_PRIV_BIT_POSITION 2 /* bit 2 */
130 #define SPARC_PSTATE_AM_BIT_POSITION 3 /* bit 3 */
131 #define SPARC_PSTATE_PEF_BIT_POSITION 4 /* bit 4 */
132 #define SPARC_PSTATE_MM_BIT_POSITION 6 /* bit 6 */
133 #define SPARC_PSTATE_TLE_BIT_POSITION 8 /* bit 8 */
134 #define SPARC_PSTATE_CLE_BIT_POSITION 9 /* bit 9 */
135 
136 #define SPARC_FPRS_FEF_MASK 0x0100 /* bit 2 */
137 #define SPARC_FPRS_FEF_BIT_POSITION 2 /* bit 2 */
138 
139 #define SPARC_TSTATE_IE_MASK 0x00000200 /* bit 9 */
140 
141 #define SPARC_SOFTINT_TM_MASK 0x00000001 /* bit 0 */
142 #define SPARC_SOFTINT_SM_MASK 0x00010000 /* bit 16 */
143 #define SPARC_SOFTINT_TM_BIT_POSITION 1 /* bit 0 */
144 #define SPARC_SOFTINT_SM_BIT_POSITION 17 /* bit 16 */
145 
146 #define STACK_BIAS (2047)
147 
148 #ifdef ASM
149 
150 /*
151  * To enable the FPU we need to set both PSTATE.pef and FPRS.fef
152  */
153 
154 #define sparc64_enable_FPU(rtmp1) \
155  rdpr %pstate, rtmp1; \
156  or rtmp1, SPARC_PSTATE_PEF_MASK, rtmp1; \
157  wrpr %g0, rtmp1, %pstate; \
158  rd %fprs, rtmp1; \
159  or rtmp1, SPARC_FPRS_FEF_MASK, rtmp1; \
160  wr %g0, rtmp1, %fprs
161 
162 
163 #endif
164 
165 #ifndef ASM
166 
167 /*
168  * Standard nop
169  */
170 
171 #define nop() \
172  do { \
173  __asm__ volatile ( "nop" ); \
174  } while ( 0 )
175 
176 /*
177  * Get and set the pstate
178  */
179 
180 #define sparc64_get_pstate( _pstate ) \
181  do { \
182  (_pstate) = 0; \
183  __asm__ volatile( "rdpr %%pstate, %0" : "=r" (_pstate) : "0" (_pstate) ); \
184  } while ( 0 )
185 
186 #define sparc64_set_pstate( _pstate ) \
187  do { \
188  __asm__ volatile ( \
189  "wrpr %%g0, %0, %%pstate " : "=r" ((_pstate)) : "0" ((_pstate)) ); \
190  } while ( 0 )
191 
192 /*
193  * Get and set the PIL
194  */
195 
196 #define sparc64_get_pil( _pil ) \
197  do { \
198  (_pil) = 0; \
199  __asm__ volatile( "rdpr %%pil, %0" : "=r" (_pil) : "0" (_pil) ); \
200  } while ( 0 )
201 
202 #define sparc64_set_pil( _pil ) \
203  do { \
204  __asm__ volatile ( "wrpr %%g0, %0, %%pil " : "=r" ((_pil)) : "0" ((_pil)) ); \
205  } while ( 0 )
206 
207 
208 /*
209  * Get and set the TBA
210  */
211 
212 #define sparc64_get_tba( _tba ) \
213  do { \
214  (_tba) = 0; /* to avoid unitialized warnings */ \
215  __asm__ volatile( "rdpr %%tba, %0" : "=r" (_tba) : "0" (_tba) ); \
216  } while ( 0 )
217 
218 #define sparc64_set_tba( _tba ) \
219  do { \
220  __asm__ volatile( "wrpr %%g0, %0, %%tba" : "=r" (_tba) : "0" (_tba) ); \
221  } while ( 0 )
222 
223 /*
224  * Get and set the TL (trap level)
225  */
226 
227 #define sparc64_get_tl( _tl ) \
228  do { \
229  (_tl) = 0; /* to avoid unitialized warnings */ \
230  __asm__ volatile( "rdpr %%tl, %0" : "=r" (_tl) : "0" (_tl) ); \
231  } while ( 0 )
232 
233 #define sparc64_set_tl( _tl ) \
234  do { \
235  __asm__ volatile( "wrpr %%g0, %0, %%tl" : "=r" (_tl) : "0" (_tl) ); \
236  } while ( 0 )
237 
238 
239 /*
240  * read the stick register
241  *
242  * Note:
243  * stick asr=24, mnemonic=stick
244  * Note: stick does not appear to be a valid ASR for US3, although it is
245  * implemented in US3i.
246  */
247 #define sparc64_read_stick( _stick ) \
248  do { \
249  (_stick) = 0; \
250  __asm__ volatile( "rd %%stick, %0" : "=r" (_stick) : "0" (_stick) ); \
251  } while ( 0 )
252 
253 /*
254  * write the stick_cmpr register
255  *
256  * Note:
257  * stick_cmpr asr=25, mnemonic=stick_cmpr
258  * Note: stick_cmpr does not appear to be a valid ASR for US3, although it is
259  * implemented in US3i.
260  */
261 #define sparc64_write_stick_cmpr( _stick_cmpr ) \
262  do { \
263  __asm__ volatile( "wr %%g0, %0, %%stick_cmpr" : "=r" (_stick_cmpr) \
264  : "0" (_stick_cmpr) ); \
265  } while ( 0 )
266 
267 /*
268  * read the Tick register
269  */
270 #define sparc64_read_tick( _tick ) \
271  do { \
272  (_tick) = 0; \
273  __asm__ volatile( "rd %%tick, %0" : "=r" (_tick) : "0" (_tick) ); \
274  } while ( 0 )
275 
276 /*
277  * write the tick_cmpr register
278  */
279 #define sparc64_write_tick_cmpr( _tick_cmpr ) \
280  do { \
281  __asm__ volatile( "wr %%g0, %0, %%tick_cmpr" : "=r" (_tick_cmpr) \
282  : "0" (_tick_cmpr) ); \
283  } while ( 0 )
284 
285 /*
286  * Clear the softint register.
287  *
288  * sun4u and sun4v: softint_clr asr = 21, with mnemonic clear_softint
289  */
290 #define sparc64_clear_interrupt_bits( _bit_mask ) \
291  do { \
292  __asm__ volatile( "wr %%g0, %0, %%clear_softint" : "=r" (_bit_mask) \
293  : "0" (_bit_mask)); \
294  } while ( 0 )
295 
296 /************* DEPRECATED ****************/
297 /* Note: Although the y register is deprecated, gcc still uses it */
298 /*
299  * Get and set the Y
300  */
301 
302 #define sparc_get_y( _y ) \
303  do { \
304  __asm__ volatile( "rd %%y, %0" : "=r" (_y) : "0" (_y) ); \
305  } while ( 0 )
306 
307 #define sparc_set_y( _y ) \
308  do { \
309  __asm__ volatile( "wr %0, %%y" : "=r" (_y) : "0" (_y) ); \
310  } while ( 0 )
311 
312 /************* /DEPRECATED ****************/
313 
314 /*
315  * Manipulate the interrupt level in the pstate
316  */
317 
318 uint32_t sparc_disable_interrupts(void);
319 void sparc_enable_interrupts(uint32_t);
320 
321 #define sparc_flash_interrupts( _level ) \
322  do { \
323  uint32_t _ignored; \
324  \
325  sparc_enable_interrupts( (_level) ); \
326  _ignored = sparc_disable_interrupts(); \
327  (void) _ignored; \
328  } while ( 0 )
329 
330 #define sparc64_get_interrupt_level( _level ) \
331  do { \
332  _level = 0; \
333  sparc64_get_pil( _level ); \
334  } while ( 0 )
335 
336 #endif /* !ASM */
337 
338 #ifdef __cplusplus
339 }
340 #endif
341 
342 #endif /* _RTEMS_SCORE_SPARC_H */