source: rtems/cpukit/score/cpu/sparc/include/rtems/score/sparc.h @ d0dd98c

Last change on this file since d0dd98c was d0dd98c, checked in by Sebastian Huber <sebastian.huber@…>, on 03/15/23 at 07:55:12

sparc: Add header files to Doxygen group

  • Property mode set to 100644
File size: 15.7 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSScoreCPUSPARC
7 *
8 * @brief This header file provides information required to build RTEMS for a
9 *   particular member of the SPARC family.
10 *
11 * This file contains the information required to build
12 * RTEMS for a particular member of the SPARC family.  It does
13 * this by setting variables to indicate which implementation
14 * dependent features are present in a particular member
15 * of the family.
16 */
17
18/*
19 *  COPYRIGHT (c) 1989-2011.
20 *  On-Line Applications Research Corporation (OAR).
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the above copyright
26 *    notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 *    notice, this list of conditions and the following disclaimer in the
29 *    documentation and/or other materials provided with the distribution.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
39 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
42 */
43
44#ifndef _RTEMS_SCORE_SPARC_H
45#define _RTEMS_SCORE_SPARC_H
46
47#include <rtems/score/basedefs.h>
48
49#ifdef __cplusplus
50extern "C" {
51#endif
52
53/*
54 *
55 *  Currently recognized feature flags:
56 *
57 *    + SPARC_HAS_FPU
58 *        0 - no HW FPU
59 *        1 - has HW FPU (assumed to be compatible w/90C602)
60 *
61 *    + SPARC_HAS_BITSCAN
62 *        0 - does not have scan instructions
63 *        1 - has scan instruction  (not currently implemented)
64 *
65 *    + SPARC_NUMBER_OF_REGISTER_WINDOWS
66 *        8 is the most common number supported by SPARC implementations.
67 *        SPARC_PSR_CWP_MASK is derived from this value.
68 */
69
70/**
71 * Some higher end SPARCs have a bitscan instructions. It would
72 * be nice to take advantage of them.  Right now, there is no
73 * port to a CPU model with this feature and no (untested) code
74 * that is based on this feature flag.
75 */
76#define SPARC_HAS_BITSCAN                0
77
78/**
79 * This should be OK until a port to a higher end SPARC processor
80 * is made that has more than 8 register windows.  If this cannot
81 * be determined based on multilib settings (v7/v8/v9), then the
82 * cpu_asm.S code that depends on this will have to move to libcpu.
83 */
84#define SPARC_NUMBER_OF_REGISTER_WINDOWS 8
85
86/**
87 * See GRLIB-TN-0009: "LEON3FT Stale Cache Entry After Store with
88 * Data Tag Parity Error"
89 */
90#if defined(__FIX_LEON3FT_B2BST)
91  #define SPARC_LEON3FT_B2BST_NOP nop
92#else
93  #define SPARC_LEON3FT_B2BST_NOP
94#endif
95
96/**
97 * This macro indicates whether this multilib variation has hardware
98 * floating point or not.  We use the gcc cpp predefine _SOFT_FLOAT
99 * to determine that.
100 */
101#if defined(_SOFT_FLOAT)
102  #define SPARC_HAS_FPU 0
103#else
104  #define SPARC_HAS_FPU 1
105#endif
106
107/**
108 * This macro contains a string describing the multilib variant being
109 * build.
110 */
111#if SPARC_HAS_FPU
112  #define CPU_MODEL_NAME "w/FPU"
113#else
114  #define CPU_MODEL_NAME "w/soft-float"
115#endif
116
117/**
118 * Define the name of the CPU family.
119 */
120#define CPU_NAME "SPARC"
121
122/*
123 *  Miscellaneous constants
124 */
125
126/**
127 * PSR masks and starting bit positions
128 *
129 * NOTE: Reserved bits are ignored.
130 */
131#if (SPARC_NUMBER_OF_REGISTER_WINDOWS == 8)
132  #define SPARC_PSR_CWP_MASK               0x07   /* bits  0 -  4 */
133#elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 16)
134  #define SPARC_PSR_CWP_MASK               0x0F   /* bits  0 -  4 */
135#elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 32)
136  #define SPARC_PSR_CWP_MASK               0x1F   /* bits  0 -  4 */
137#else
138  #error "Unsupported number of register windows for this cpu"
139#endif
140
141/** This constant is a mask for the ET bits in the PSR. */
142#define SPARC_PSR_ET_MASK   0x00000020   /* bit   5 */
143/** This constant is a mask for the PS bits in the PSR. */
144#define SPARC_PSR_PS_MASK   0x00000040   /* bit   6 */
145/** This constant is a mask for the S bits in the PSR. */
146#define SPARC_PSR_S_MASK    0x00000080   /* bit   7 */
147/** This constant is a mask for the PIL bits in the PSR. */
148#define SPARC_PSR_PIL_MASK  0x00000F00   /* bits  8 - 11 */
149/** This constant is a mask for the EF bits in the PSR. */
150#define SPARC_PSR_EF_MASK   0x00001000   /* bit  12 */
151/** This constant is a mask for the EC bits in the PSR. */
152#define SPARC_PSR_EC_MASK   0x00002000   /* bit  13 */
153/** This constant is a mask for the ICC bits in the PSR. */
154#define SPARC_PSR_ICC_MASK  0x00F00000   /* bits 20 - 23 */
155/** This constant is a mask for the VER bits in the PSR. */
156#define SPARC_PSR_VER_MASK  0x0F000000   /* bits 24 - 27 */
157/** This constant is a mask for the IMPL bits in the PSR. */
158#define SPARC_PSR_IMPL_MASK 0xF0000000   /* bits 28 - 31 */
159
160/** This constant is the starting bit position of the CWP in the PSR. */
161#define SPARC_PSR_CWP_BIT_POSITION   0   /* bits  0 -  4 */
162/** This constant is the starting bit position of the ET in the PSR. */
163#define SPARC_PSR_ET_BIT_POSITION    5   /* bit   5 */
164/** This constant is the starting bit position of the PS in the PSR. */
165#define SPARC_PSR_PS_BIT_POSITION    6   /* bit   6 */
166/** This constant is the starting bit position of the S in the PSR. */
167#define SPARC_PSR_S_BIT_POSITION     7   /* bit   7 */
168/** This constant is the starting bit position of the PIL in the PSR. */
169#define SPARC_PSR_PIL_BIT_POSITION   8   /* bits  8 - 11 */
170/** This constant is the starting bit position of the EF in the PSR. */
171#define SPARC_PSR_EF_BIT_POSITION   12   /* bit  12 */
172/** This constant is the starting bit position of the EC in the PSR. */
173#define SPARC_PSR_EC_BIT_POSITION   13   /* bit  13 */
174/** This constant is the starting bit position of the ICC in the PSR. */
175#define SPARC_PSR_ICC_BIT_POSITION  20   /* bits 20 - 23 */
176/** This constant is the starting bit position of the VER in the PSR. */
177#define SPARC_PSR_VER_BIT_POSITION  24   /* bits 24 - 27 */
178/** This constant is the starting bit position of the IMPL in the PSR. */
179#define SPARC_PSR_IMPL_BIT_POSITION 28   /* bits 28 - 31 */
180
181#define LEON3_ASR17_PROCESSOR_INDEX_SHIFT 28
182
183/* SPARC Software Trap number definitions */
184#define SPARC_SWTRAP_SYSCALL 0
185#define SPARC_SWTRAP_IRQDIS 9
186#define SPARC_SWTRAP_IRQEN 10
187#if SPARC_HAS_FPU == 1
188#define SPARC_SWTRAP_IRQDIS_FP 11
189#endif
190
191/**
192 * @brief This is the bit step in a vector number to indicate it is being
193 *   installed as a synchronous trap.
194 */
195#define SPARC_SYNCHRONOUS_TRAP_BIT_MASK 0x100
196
197/**
198 * @brief Maps the real hardware vector number to the associated asynchronous
199 *   trap number.
200 *
201 * @param _vector is the real hardware vector number to map.
202 *
203 * @return Returns the asynchronous trap number associated with the real
204 *   hardware vector number.
205 */
206#define SPARC_ASYNCHRONOUS_TRAP( _vector ) ( _vector )
207
208/**
209 * @brief Maps the real hardware vector number to the associated synchronous
210 *   trap number.
211 *
212 * @param _vector is the real hardware vector number to map.
213 *
214 * @return Returns the synchronous trap number associated with the
215 *   real hardware vector number.
216 */
217#define SPARC_SYNCHRONOUS_TRAP( _vector ) ( ( _vector ) + 256 )
218
219/**
220 * @brief Maps the synchronous or asynchronous trap number to the associated
221 *   real hardware vector number.
222 *
223 * @param _trap is the synchronous or asynchronous trap number to map.
224 *
225 * @return Returns the real hardware vector number associated with the
226 *   synchronous or asynchronous trap number.
227 */
228#define SPARC_REAL_TRAP_NUMBER( _trap ) ( ( _trap ) % 256 )
229
230/**
231 * @brief Checks if the real hardware vector number, synchronous trap number,
232 *   or asynchronous trap number is an interrupt trap.
233 *
234 * Interrupt traps are defined by Table 7-1 "Exception and Interrupt Request
235 * Priority and tt Values" in "The SPARC Architecture Manual: Version 8".
236 *
237 * @param _trap is the real hardware vector number, synchronous trap number, or
238 *   asynchronous trap number to check.
239 *
240 * @return Returns true, if the real hardware vector number, synchronous trap
241 *   number, or asynchronous trap number is an interrupt trap, otherwise false.
242 */
243#define SPARC_IS_INTERRUPT_TRAP( _trap ) \
244  ( SPARC_REAL_TRAP_NUMBER( _trap ) >= 0x11 && \
245    SPARC_REAL_TRAP_NUMBER( _trap ) <= 0x1f )
246
247/**
248 * @brief Maps the interrupt trap number to the associated interrupt source
249 *   number.
250 *
251 * Interrupt trap numbers are real hardware vector numbers, synchronous trap
252 * numbers, and asynchronous trap numbers for which SPARC_IS_INTERRUPT_TRAP()
253 * returns true.
254 *
255 * @param _trap is the real hardware vector number, synchronous trap number, or
256 *   asynchronous trap number to map.
257 *
258 * @return Returns the interrupt source number associated with the interrupt
259 *   trap number.
260 */
261#define SPARC_INTERRUPT_TRAP_TO_SOURCE( _trap ) \
262  ( SPARC_REAL_TRAP_NUMBER( _trap ) - 0x10 )
263
264/**
265 * @brief Maps the interrupt source number to the associated asynchronous trap
266 *   number.
267 *
268 * @param _source is the interrupt source number to map.
269 *
270 * @return Returns the asynchronous trap number associated with the interrupt
271 *   source number.
272 */
273#define SPARC_INTERRUPT_SOURCE_TO_TRAP( _source ) \
274  ( SPARC_ASYNCHRONOUS_TRAP( _source ) + 0x10 )
275
276#ifndef ASM
277
278/**
279 * This macro is a standard nop instruction.
280 */
281#define nop() \
282  do { \
283    __asm__ volatile ( "nop" ); \
284  } while ( 0 )
285
286/**
287 * @brief Macro to obtain the PSR.
288 *
289 * This macro returns the current contents of the PSR register in @a _psr.
290 */
291#if defined(RTEMS_PARAVIRT)
292
293uint32_t _SPARC_Get_PSR( void );
294
295#define sparc_get_psr( _psr ) \
296  (_psr) = _SPARC_Get_PSR()
297
298#else /* RTEMS_PARAVIRT */
299
300#define sparc_get_psr( _psr ) \
301  do { \
302     (_psr) = 0; \
303     __asm__ volatile( "rd %%psr, %0" :  "=r" (_psr) : "0" (_psr) ); \
304  } while ( 0 )
305
306#endif /* RTEMS_PARAVIRT */
307
308/**
309 * @brief Macro to set the PSR.
310 *
311 * This macro sets the PSR register to the value in @a _psr.
312 */
313#if defined(RTEMS_PARAVIRT)
314
315void _SPARC_Set_PSR( uint32_t new_psr );
316
317#define sparc_set_psr( _psr ) \
318  _SPARC_Set_PSR( _psr )
319
320#else /* RTEMS_PARAVIRT */
321
322#define sparc_set_psr( _psr ) \
323  do { \
324    __asm__ volatile ( "mov  %0, %%psr " : "=r" ((_psr)) : "0" ((_psr)) ); \
325    nop(); \
326    nop(); \
327    nop(); \
328  } while ( 0 )
329
330#endif /* RTEMS_PARAVIRT */
331
332/**
333 * @brief Macro to obtain the TBR.
334 *
335 * This macro returns the current contents of the TBR register in @a _tbr.
336 */
337#if defined(RTEMS_PARAVIRT)
338
339uint32_t _SPARC_Get_TBR( void );
340
341#define sparc_get_tbr( _tbr ) \
342  (_tbr) = _SPARC_Get_TBR()
343
344#else /* RTEMS_PARAVIRT */
345
346#define sparc_get_tbr( _tbr ) \
347  do { \
348     (_tbr) = 0; /* to avoid unitialized warnings */ \
349     __asm__ volatile( "rd %%tbr, %0" :  "=r" (_tbr) : "0" (_tbr) ); \
350  } while ( 0 )
351
352#endif /* RTEMS_PARAVIRT */
353
354/**
355 * @brief Macro to set the TBR.
356 *
357 * This macro sets the TBR register to the value in @a _tbr.
358 */
359#if defined(RTEMS_PARAVIRT)
360
361void _SPARC_Set_TBR( uint32_t new_tbr );
362
363#define sparc_set_tbr( _tbr ) \
364  _SPARC_Set_TBR((_tbr))
365
366#else /* RTEMS_PARAVIRT */
367
368#define sparc_set_tbr( _tbr ) \
369  do { \
370     __asm__ volatile( "wr %0, 0, %%tbr" :  "=r" (_tbr) : "0" (_tbr) ); \
371  } while ( 0 )
372
373#endif /* RTEMS_PARAVIRT */
374
375/**
376 * @brief Macro to obtain the WIM.
377 *
378 * This macro returns the current contents of the WIM field in @a _wim.
379 */
380#define sparc_get_wim( _wim ) \
381  do { \
382    __asm__ volatile( "rd %%wim, %0" :  "=r" (_wim) : "0" (_wim) ); \
383  } while ( 0 )
384
385/**
386 * @brief Macro to set the WIM.
387 *
388 * This macro sets the WIM field to the value in @a _wim.
389 */
390#define sparc_set_wim( _wim ) \
391  do { \
392    __asm__ volatile( "wr %0, %%wim" :  "=r" (_wim) : "0" (_wim) ); \
393    nop(); \
394    nop(); \
395    nop(); \
396  } while ( 0 )
397
398/**
399 * @brief Macro to obtain the Y register.
400 *
401 * This macro returns the current contents of the Y register in @a _y.
402 */
403#define sparc_get_y( _y ) \
404  do { \
405    __asm__ volatile( "rd %%y, %0" :  "=r" (_y) : "0" (_y) ); \
406  } while ( 0 )
407
408/**
409 * @brief Macro to set the Y register.
410 *
411 * This macro sets the Y register to the value in @a _y.
412 */
413#define sparc_set_y( _y ) \
414  do { \
415    __asm__ volatile( "wr %0, %%y" :  "=r" (_y) : "0" (_y) ); \
416  } while ( 0 )
417
418/**
419 * @brief SPARC disable processor interrupts.
420 *
421 * This method is invoked to disable all maskable interrupts.
422 *
423 * @return This method returns the entire PSR contents.
424 */
425static inline uint32_t sparc_disable_interrupts(void)
426{
427  register uint32_t psr __asm__("g1"); /* return value of trap handler */
428#ifdef __FIX_LEON3FT_TN0018
429  __asm__ volatile ( "ta %1\n\tnop\n\t" : "=r" (psr) : "i" (SPARC_SWTRAP_IRQDIS));
430#else
431  __asm__ volatile ( "ta %1\n\t" : "=r" (psr) : "i" (SPARC_SWTRAP_IRQDIS));
432#endif
433  return psr;
434}
435
436/**
437 * @brief SPARC enable processor interrupts.
438 *
439 * This method is invoked to enable all maskable interrupts.
440 *
441 * @param[in] psr is the PSR returned by @ref sparc_disable_interrupts.
442 */
443static inline void sparc_enable_interrupts(uint32_t psr)
444{
445  register uint32_t _psr __asm__("g1") = psr; /* input to trap handler */
446
447  /*
448   * The trap instruction has a higher trap priority than the interrupts
449   * according to "The SPARC Architecture Manual: Version 8", Table 7-1
450   * "Exception and Interrupt Request Priority and tt Values".  Add a nop to
451   * prevent a trap instruction right after the interrupt enable trap.
452   */
453  __asm__ volatile ( "ta %0\nnop\n" :: "i" (SPARC_SWTRAP_IRQEN), "r" (_psr));
454}
455
456/**
457 * @brief SPARC exit through system call 1
458 *
459 * This method is invoked to go into system error halt. The optional
460 * arguments can be given to hypervisor, hardware debugger, simulator or
461 * similar.
462 *
463 * System error mode is entered when taking a trap when traps have been
464 * disabled. What happens when error mode is entered depends on the motherboard.
465 * In a typical development systems the CPU relingish control to the debugger,
466 * simulator, hypervisor or similar. The following steps are taken:
467 *
468 * 1. Going into system error mode by Software Trap 0
469 * 2. %g1=1 (syscall 1 - Exit)
470 * 3. %g2=Primary exit code
471 * 4. %g3=Secondary exit code. Dependends on %g2 exit type.
472 *
473 * This function never returns.
474 *
475 * @param[in] exitcode1 Primary exit code stored in CPU g2 register after exit
476 * @param[in] exitcode2 Primary exit code stored in CPU g3 register after exit
477 */
478RTEMS_NO_RETURN void sparc_syscall_exit(
479  uint32_t exitcode1,
480  uint32_t exitcode2
481);
482
483/**
484 * @brief SPARC flash processor interrupts.
485 *
486 * This method is invoked to temporarily enable all maskable interrupts.
487 *
488 * @param[in] _psr is the PSR returned by @ref sparc_disable_interrupts.
489 */
490#define sparc_flash_interrupts( _psr ) \
491  do { \
492    sparc_enable_interrupts( (_psr) ); \
493    _psr = sparc_disable_interrupts(); \
494  } while ( 0 )
495
496/**
497 * @brief SPARC obtain interrupt level.
498 *
499 * This method is invoked to obtain the current interrupt disable level.
500 *
501 * @param[in] _level is the PSR returned by @ref sparc_disable_interrupts.
502 */
503#define sparc_get_interrupt_level( _level ) \
504  do { \
505    uint32_t _psr_level = 0; \
506    \
507    sparc_get_psr( _psr_level ); \
508    (_level) = \
509      (_psr_level & SPARC_PSR_PIL_MASK) >> SPARC_PSR_PIL_BIT_POSITION; \
510  } while ( 0 )
511
512static inline uint32_t _LEON3_Get_current_processor( void )
513{
514  uint32_t asr17;
515
516  __asm__ volatile (
517    "rd %%asr17, %0"
518    : "=&r" (asr17)
519  );
520
521  return asr17 >> LEON3_ASR17_PROCESSOR_INDEX_SHIFT;
522}
523
524#endif /* ASM */
525
526#ifdef __cplusplus
527}
528#endif
529
530#endif /* _RTEMS_SCORE_SPARC_H */
Note: See TracBrowser for help on using the repository browser.