source: rtems/cpukit/score/cpu/sparc/rtems/score/sparc.h @ dff1803

4.115
Last change on this file since dff1803 was dff1803, checked in by Daniel Hellstrom <daniel@…>, on 12/03/14 at 10:35:52

SPARC: optimize IRQ enable & disable

  • Coding style cleanups.
  • Use OS reserved trap 0x89 for IRQ Disable
  • Use OS reserved trap 0x8A for IRQ Enable
  • Add to SPARC CPU supplement documentation

This will result in faster Disable/Enable? code since the
system trap handler does not need to decode which function
the user wants. Besides the IRQ disable/enabled can now
be inline which avoids the caller to take into account that
o0-o7+g1-g4 registers are destroyed by trap handler.

It was also possible to reduce the interrupt trap handler by
five instructions due to this.

  • Property mode set to 100644
File size: 11.0 KB
RevLine 
[f4ae0c5]1/**
[1362b7a]2 * @file
3 *
4 * @brief Information Required to Build RTEMS for a Particular Member
5 * of the SPARC Family
[4bafde5]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.
[f4ae0c5]12 */
13
14/*
[4bafde5]15 *  COPYRIGHT (c) 1989-2011.
[7908ba5b]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
[c499856]20 *  http://www.rtems.org/license/LICENSE.
[7908ba5b]21 */
22
[7f70d1b7]23#ifndef _RTEMS_SCORE_SPARC_H
24#define _RTEMS_SCORE_SPARC_H
[7908ba5b]25
[ad4ef3c]26#include <rtems/score/types.h>
[b1ce6f29]27
[7908ba5b]28#ifdef __cplusplus
29extern "C" {
30#endif
31
32/*
33 *
34 *  Currently recognized feature flags:
35 *
[80f7732]36 *    + SPARC_HAS_FPU
[7908ba5b]37 *        0 - no HW FPU
38 *        1 - has HW FPU (assumed to be compatible w/90C602)
39 *
[80f7732]40 *    + SPARC_HAS_BITSCAN
[7908ba5b]41 *        0 - does not have scan instructions
42 *        1 - has scan instruction  (not currently implemented)
[80f7732]43 *
[7908ba5b]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 */
[80f7732]48
[4bafde5]49/**
[1362b7a]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.
[df49c60]54 */
55#define SPARC_HAS_BITSCAN                0
56
[4bafde5]57/**
[1362b7a]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.
[4159370]62 */
[7908ba5b]63#define SPARC_NUMBER_OF_REGISTER_WINDOWS 8
[80f7732]64
[4bafde5]65/**
[1362b7a]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.
[4159370]69 */
[477e2d19]70#if defined(_SOFT_FLOAT)
[4bafde5]71  #define SPARC_HAS_FPU 0
[477e2d19]72#else
[4bafde5]73  #define SPARC_HAS_FPU 1
[477e2d19]74#endif
[4159370]75
[4bafde5]76/**
[1362b7a]77 * This macro contains a string describing the multilib variant being
78 * build.
[4bafde5]79 */
[4159370]80#if SPARC_HAS_FPU
[4bafde5]81  #define CPU_MODEL_NAME "w/FPU"
[7908ba5b]82#else
[4bafde5]83  #define CPU_MODEL_NAME "w/soft-float"
[7908ba5b]84#endif
85
[4bafde5]86/**
[1362b7a]87 * Define the name of the CPU family.
[7908ba5b]88 */
89#define CPU_NAME "SPARC"
90
91/*
92 *  Miscellaneous constants
93 */
94
[4bafde5]95/**
[1362b7a]96 * PSR masks and starting bit positions
[7908ba5b]97 *
[1362b7a]98 * NOTE: Reserved bits are ignored.
[7908ba5b]99 */
100#if (SPARC_NUMBER_OF_REGISTER_WINDOWS == 8)
[4bafde5]101  #define SPARC_PSR_CWP_MASK               0x07   /* bits  0 -  4 */
[7908ba5b]102#elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 16)
[4bafde5]103  #define SPARC_PSR_CWP_MASK               0x0F   /* bits  0 -  4 */
[7908ba5b]104#elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 32)
[4bafde5]105  #define SPARC_PSR_CWP_MASK               0x1F   /* bits  0 -  4 */
[7908ba5b]106#else
[4bafde5]107  #error "Unsupported number of register windows for this cpu"
[7908ba5b]108#endif
109
[4bafde5]110/** This constant is a mask for the ET bits in the PSR. */
[7908ba5b]111#define SPARC_PSR_ET_MASK   0x00000020   /* bit   5 */
[4bafde5]112/** This constant is a mask for the PS bits in the PSR. */
[7908ba5b]113#define SPARC_PSR_PS_MASK   0x00000040   /* bit   6 */
[4bafde5]114/** This constant is a mask for the S bits in the PSR. */
[7908ba5b]115#define SPARC_PSR_S_MASK    0x00000080   /* bit   7 */
[4bafde5]116/** This constant is a mask for the PIL bits in the PSR. */
[7908ba5b]117#define SPARC_PSR_PIL_MASK  0x00000F00   /* bits  8 - 11 */
[4bafde5]118/** This constant is a mask for the EF bits in the PSR. */
[7908ba5b]119#define SPARC_PSR_EF_MASK   0x00001000   /* bit  12 */
[4bafde5]120/** This constant is a mask for the EC bits in the PSR. */
[7908ba5b]121#define SPARC_PSR_EC_MASK   0x00002000   /* bit  13 */
[4bafde5]122/** This constant is a mask for the ICC bits in the PSR. */
[7908ba5b]123#define SPARC_PSR_ICC_MASK  0x00F00000   /* bits 20 - 23 */
[4bafde5]124/** This constant is a mask for the VER bits in the PSR. */
[7908ba5b]125#define SPARC_PSR_VER_MASK  0x0F000000   /* bits 24 - 27 */
[4bafde5]126/** This constant is a mask for the IMPL bits in the PSR. */
[7908ba5b]127#define SPARC_PSR_IMPL_MASK 0xF0000000   /* bits 28 - 31 */
128
[4bafde5]129/** This constant is the starting bit position of the CWP in the PSR. */
[7908ba5b]130#define SPARC_PSR_CWP_BIT_POSITION   0   /* bits  0 -  4 */
[4bafde5]131/** This constant is the starting bit position of the ET in the PSR. */
[7908ba5b]132#define SPARC_PSR_ET_BIT_POSITION    5   /* bit   5 */
[4bafde5]133/** This constant is the starting bit position of the PS in the PSR. */
[7908ba5b]134#define SPARC_PSR_PS_BIT_POSITION    6   /* bit   6 */
[4bafde5]135/** This constant is the starting bit position of the S in the PSR. */
[7908ba5b]136#define SPARC_PSR_S_BIT_POSITION     7   /* bit   7 */
[4bafde5]137/** This constant is the starting bit position of the PIL in the PSR. */
[7908ba5b]138#define SPARC_PSR_PIL_BIT_POSITION   8   /* bits  8 - 11 */
[4bafde5]139/** This constant is the starting bit position of the EF in the PSR. */
[7908ba5b]140#define SPARC_PSR_EF_BIT_POSITION   12   /* bit  12 */
[4bafde5]141/** This constant is the starting bit position of the EC in the PSR. */
[7908ba5b]142#define SPARC_PSR_EC_BIT_POSITION   13   /* bit  13 */
[4bafde5]143/** This constant is the starting bit position of the ICC in the PSR. */
[7908ba5b]144#define SPARC_PSR_ICC_BIT_POSITION  20   /* bits 20 - 23 */
[4bafde5]145/** This constant is the starting bit position of the VER in the PSR. */
[7908ba5b]146#define SPARC_PSR_VER_BIT_POSITION  24   /* bits 24 - 27 */
[4bafde5]147/** This constant is the starting bit position of the IMPL in the PSR. */
[7908ba5b]148#define SPARC_PSR_IMPL_BIT_POSITION 28   /* bits 28 - 31 */
149
[ad56361]150#define LEON3_ASR17_PROCESSOR_INDEX_SHIFT 28
151
[dff1803]152/* SPARC Software Trap number definitions */
153#define SPARC_SWTRAP_SYSCALL 0
154#define SPARC_SWTRAP_IRQDIS 9
155#define SPARC_SWTRAP_IRQEN 10
156
[7908ba5b]157#ifndef ASM
158
[4bafde5]159/**
[1362b7a]160 * This macro is a standard nop instruction.
[7908ba5b]161 */
162#define nop() \
163  do { \
[e4a2a21f]164    __asm__ volatile ( "nop" ); \
[7908ba5b]165  } while ( 0 )
166
[4bafde5]167/**
[1362b7a]168 * @brief Macro to obtain the PSR.
[4bafde5]169 *
[1362b7a]170 * This macro returns the current contents of the PSR register in @a _psr.
[7908ba5b]171 */
[8df1f408]172#if defined(RTEMS_PARAVIRT)
173
174uint32_t _SPARC_Get_PSR( void );
175
176#define sparc_get_psr( _psr ) \
177  (_psr) = _SPARC_Get_PSR()
178
179#else /* RTEMS_PARAVIRT */
180
[7908ba5b]181#define sparc_get_psr( _psr ) \
182  do { \
183     (_psr) = 0; \
[e4a2a21f]184     __asm__ volatile( "rd %%psr, %0" :  "=r" (_psr) : "0" (_psr) ); \
[7908ba5b]185  } while ( 0 )
186
[8df1f408]187#endif /* RTEMS_PARAVIRT */
188
[4bafde5]189/**
[1362b7a]190 * @brief Macro to set the PSR.
[4bafde5]191 *
[1362b7a]192 * This macro sets the PSR register to the value in @a _psr.
[4bafde5]193 */
[8df1f408]194#if defined(RTEMS_PARAVIRT)
195
196void _SPARC_Set_PSR( uint32_t new_psr );
197
198#define sparc_set_psr( _psr ) \
199  _SPARC_Set_PSR( _psr )
200
201#else /* RTEMS_PARAVIRT */
202
[7908ba5b]203#define sparc_set_psr( _psr ) \
204  do { \
[e4a2a21f]205    __asm__ volatile ( "mov  %0, %%psr " : "=r" ((_psr)) : "0" ((_psr)) ); \
[7908ba5b]206    nop(); \
207    nop(); \
208    nop(); \
209  } while ( 0 )
210
[8df1f408]211#endif /* RTEMS_PARAVIRT */
212
[4bafde5]213/**
[1362b7a]214 * @brief Macro to obtain the TBR.
[4bafde5]215 *
[1362b7a]216 * This macro returns the current contents of the TBR register in @a _tbr.
[7908ba5b]217 */
[8df1f408]218#if defined(RTEMS_PARAVIRT)
219
220uint32_t _SPARC_Get_TBR( void );
221
222#define sparc_get_tbr( _tbr ) \
223  (_tbr) = _SPARC_Get_TBR()
224
225#else /* RTEMS_PARAVIRT */
226
[7908ba5b]227#define sparc_get_tbr( _tbr ) \
228  do { \
229     (_tbr) = 0; /* to avoid unitialized warnings */ \
[e4a2a21f]230     __asm__ volatile( "rd %%tbr, %0" :  "=r" (_tbr) : "0" (_tbr) ); \
[7908ba5b]231  } while ( 0 )
232
[8df1f408]233#endif /* RTEMS_PARAVIRT */
234
[4bafde5]235/**
[1362b7a]236 * @brief Macro to set the TBR.
[4bafde5]237 *
[1362b7a]238 * This macro sets the TBR register to the value in @a _tbr.
[4bafde5]239 */
[8df1f408]240#if defined(RTEMS_PARAVIRT)
241
242void _SPARC_Set_TBR( uint32_t new_tbr );
243
244#define sparc_set_tbr( _tbr ) \
245  _SPARC_Set_TBR((_tbr))
246
247#else /* RTEMS_PARAVIRT */
248
[7908ba5b]249#define sparc_set_tbr( _tbr ) \
250  do { \
[e4a2a21f]251     __asm__ volatile( "wr %0, 0, %%tbr" :  "=r" (_tbr) : "0" (_tbr) ); \
[7908ba5b]252  } while ( 0 )
253
[8df1f408]254#endif /* RTEMS_PARAVIRT */
255
[4bafde5]256/**
[1362b7a]257 * @brief Macro to obtain the WIM.
[4bafde5]258 *
[1362b7a]259 * This macro returns the current contents of the WIM field in @a _wim.
[7908ba5b]260 */
261#define sparc_get_wim( _wim ) \
262  do { \
[e4a2a21f]263    __asm__ volatile( "rd %%wim, %0" :  "=r" (_wim) : "0" (_wim) ); \
[7908ba5b]264  } while ( 0 )
265
[4bafde5]266/**
[1362b7a]267 * @brief Macro to set the WIM.
[4bafde5]268 *
[1362b7a]269 * This macro sets the WIM field to the value in @a _wim.
[4bafde5]270 */
[7908ba5b]271#define sparc_set_wim( _wim ) \
272  do { \
[e4a2a21f]273    __asm__ volatile( "wr %0, %%wim" :  "=r" (_wim) : "0" (_wim) ); \
[7908ba5b]274    nop(); \
275    nop(); \
276    nop(); \
277  } while ( 0 )
278
[4bafde5]279/**
[1362b7a]280 * @brief Macro to obtain the Y register.
[4bafde5]281 *
[1362b7a]282 * This macro returns the current contents of the Y register in @a _y.
[7908ba5b]283 */
284#define sparc_get_y( _y ) \
285  do { \
[e4a2a21f]286    __asm__ volatile( "rd %%y, %0" :  "=r" (_y) : "0" (_y) ); \
[7908ba5b]287  } while ( 0 )
[80f7732]288
[4bafde5]289/**
[1362b7a]290 * @brief Macro to set the Y register.
[4bafde5]291 *
[1362b7a]292 * This macro sets the Y register to the value in @a _y.
[4bafde5]293 */
[7908ba5b]294#define sparc_set_y( _y ) \
295  do { \
[e4a2a21f]296    __asm__ volatile( "wr %0, %%y" :  "=r" (_y) : "0" (_y) ); \
[7908ba5b]297  } while ( 0 )
298
[4bafde5]299/**
[1362b7a]300 * @brief SPARC disable processor interrupts.
[4bafde5]301 *
[1362b7a]302 * This method is invoked to disable all maskable interrupts.
[4bafde5]303 *
[1362b7a]304 * @return This method returns the entire PSR contents.
[7908ba5b]305 */
[dff1803]306static inline uint32_t sparc_disable_interrupts(void)
307{
308  register uint32_t psr __asm__("g1"); /* return value of trap handler */
309  __asm__ volatile ( "ta %1\n\t" : "=r" (psr) : "i" (SPARC_SWTRAP_IRQDIS));
310  return psr;
311}
[80f7732]312
[4bafde5]313/**
[1362b7a]314 * @brief SPARC enable processor interrupts.
[4bafde5]315 *
[1362b7a]316 * This method is invoked to enable all maskable interrupts.
[4bafde5]317 *
[1362b7a]318 * @param[in] psr is the PSR returned by @ref sparc_disable_interrupts.
[4bafde5]319 */
[dff1803]320static inline void sparc_enable_interrupts(uint32_t psr)
321{
322  register uint32_t _psr __asm__("g1") = psr; /* input to trap handler */
323  __asm__ volatile ( "ta %0\n" :: "i" (SPARC_SWTRAP_IRQEN), "r" (_psr));
324}
[4bafde5]325
[6a740c2]326/**
327 * @brief SPARC exit through system call 1
328 *
329 * This method is invoked to go into system error halt. The optional
330 * arguments can be given to hypervisor, hardware debugger, simulator or
331 * similar.
332 *
333 * System error mode is entered when taking a trap when traps have been
334 * disabled. What happens when error mode is entered depends on the motherboard.
335 * In a typical development systems the CPU relingish control to the debugger,
336 * simulator, hypervisor or similar. The following steps are taken:
337 *
338 * 1. Going into system error mode by Software Trap 0
339 * 2. %g1=1 (syscall 1 - Exit)
340 * 3. %g2=Primary exit code
341 * 4. %g3=Secondary exit code. Dependends on %g2 exit type.
342 *
343 * This function never returns.
344 *
345 * @param[in] exitcode1 Primary exit code stored in CPU g2 register after exit
346 * @param[in] exitcode2 Primary exit code stored in CPU g3 register after exit
347 */
348void sparc_syscall_exit(uint32_t exitcode1, uint32_t exitcode2)
349  RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
350
[4bafde5]351/**
[1362b7a]352 * @brief SPARC flash processor interrupts.
[4bafde5]353 *
[1362b7a]354 * This method is invoked to temporarily enable all maskable interrupts.
[4bafde5]355 *
[1362b7a]356 * @param[in] _psr is the PSR returned by @ref sparc_disable_interrupts.
[4bafde5]357 */
358#define sparc_flash_interrupts( _psr ) \
[7908ba5b]359  do { \
[4bafde5]360    sparc_enable_interrupts( (_psr) ); \
361    _psr = sparc_disable_interrupts(); \
[7908ba5b]362  } while ( 0 )
363
[4bafde5]364/**
[1362b7a]365 * @brief SPARC obtain interrupt level.
[4bafde5]366 *
[1362b7a]367 * This method is invoked to obtain the current interrupt disable level.
[4bafde5]368 *
[1362b7a]369 * @param[in] _level is the PSR returned by @ref sparc_disable_interrupts.
[4bafde5]370 */
[7908ba5b]371#define sparc_get_interrupt_level( _level ) \
372  do { \
[2a0a6851]373    register uint32_t   _psr_level = 0; \
[7908ba5b]374    \
375    sparc_get_psr( _psr_level ); \
376    (_level) = \
377      (_psr_level & SPARC_PSR_PIL_MASK) >> SPARC_PSR_PIL_BIT_POSITION; \
378  } while ( 0 )
379
[ad56361]380static inline uint32_t _LEON3_Get_current_processor( void )
381{
382  uint32_t asr17;
383
[47d60134]384  __asm__ volatile (
[ad56361]385    "rd %%asr17, %0"
386    : "=&r" (asr17)
387  );
388
389  return asr17 >> LEON3_ASR17_PROCESSOR_INDEX_SHIFT;
390}
391
[7908ba5b]392#endif
393
394#ifdef __cplusplus
395}
396#endif
397
[f6ed46df]398#endif /* _RTEMS_SCORE_SPARC_H */
Note: See TracBrowser for help on using the repository browser.