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

Last change on this file since d7a48e1 was d7a48e1, checked in by Sebastian Huber <sebastian.huber@…>, on 10/06/20 at 05:39:44

rtems: Improve RTEMS_NO_RETURN attribute

Provide RTEMS_NO_RETURN also in case RTEMS_DEBUG is defined to prevent errors
like this:

error: no return statement in function returning non-void [-Werror=return-type]

Use C11 and C++11 standard means to declare a no-return function.

Close #4122.

  • Property mode set to 100644
File size: 38.5 KB
Line 
1/**
2 * @file
3 *
4 * @brief SPARC CPU Department Source
5 *
6 * This include file contains information pertaining to the port of
7 * the executive to the SPARC processor.
8 */
9
10/*
11 *  COPYRIGHT (c) 1989-2011.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#ifndef _RTEMS_SCORE_CPU_H
20#define _RTEMS_SCORE_CPU_H
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26#include <rtems/score/basedefs.h>
27#include <rtems/score/sparc.h>
28
29/* conditional compilation parameters */
30
31/*
32 * The SPARC ABI is a bit special with respect to the floating point context.
33 * The complete floating point context is volatile.  Thus, from an ABI point
34 * of view nothing needs to be saved and restored during a context switch.
35 * Instead the floating point context must be saved and restored during
36 * interrupt processing.  Historically, the deferred floating point switch was
37 * used for SPARC and the complete floating point context is saved and
38 * restored during a context switch to the new floating point unit owner.
39 * This is a bit dangerous since post-switch actions (e.g. signal handlers)
40 * and context switch extensions may silently corrupt the floating point
41 * context.
42 *
43 * The floating point unit is disabled for interrupt handlers.  Thus, in case
44 * an interrupt handler uses the floating point unit then this will result in a
45 * trap (INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT).
46 *
47 * In uniprocessor configurations, a lazy floating point context switch is
48 * used.  In case an active floating point thread is interrupted (PSR[EF] == 1)
49 * and a thread dispatch is carried out, then this thread is registered as the
50 * floating point owner.  When a floating point owner is present during a
51 * context switch, the floating point unit is disabled for the heir thread
52 * (PSR[EF] == 0).  The floating point disabled trap checks that the use of the
53 * floating point unit is allowed and saves/restores the floating point context
54 * on demand.
55 *
56 * In SMP configurations, the deferred floating point switch is not supported
57 * in principle.  So, use here a synchronous floating point switching.
58 * Synchronous means that the volatile floating point context is saved and
59 * restored around a thread dispatch issued during interrupt processing.  Thus
60 * post-switch actions and context switch extensions may safely use the
61 * floating point unit.
62 */
63#if SPARC_HAS_FPU == 1
64  #if defined(RTEMS_SMP)
65    #define SPARC_USE_SYNCHRONOUS_FP_SWITCH
66  #else
67    #define SPARC_USE_LAZY_FP_SWITCH
68  #endif
69#endif
70
71/**
72 * Does the CPU follow the simple vectored interrupt model?
73 *
74 * - If TRUE, then RTEMS allocates the vector table it internally manages.
75 * - If FALSE, then the BSP is assumed to allocate and manage the vector
76 *   table
77 *
78 * THe SPARC is a simple vectored architecture.  Usually there is no
79 * PIC and the CPU directly vectors the interrupts.
80 */
81#define CPU_SIMPLE_VECTORED_INTERRUPTS TRUE
82
83/**
84 * Does the RTEMS invoke the user's ISR with the vector number and
85 * a pointer to the saved interrupt frame (1) or just the vector
86 * number (0)?
87 *
88 * The SPARC port does not pass an Interrupt Stack Frame pointer to
89 * interrupt handlers.
90 */
91#define CPU_ISR_PASSES_FRAME_POINTER FALSE
92
93/**
94 * Does the CPU have hardware floating point?
95 *
96 * - If TRUE, then the FLOATING_POINT task attribute is supported.
97 * - If FALSE, then the FLOATING_POINT task attribute is ignored.
98 *
99 * This is set based upon the multilib settings.
100 */
101#if ( SPARC_HAS_FPU == 1 ) && !defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
102  #define CPU_HARDWARE_FP     TRUE
103#else
104  #define CPU_HARDWARE_FP     FALSE
105#endif
106
107/**
108 * The SPARC GCC port does not have a software floating point library
109 * that requires RTEMS assistance.
110 */
111#define CPU_SOFTWARE_FP     FALSE
112
113/**
114 * Are all tasks FLOATING_POINT tasks implicitly?
115 *
116 * - If TRUE, then the FLOATING_POINT task attribute is assumed.
117 * - If FALSE, then the FLOATING_POINT task attribute is followed.
118 *
119 * The SPARC GCC port does not implicitly use floating point registers.
120 */
121#define CPU_ALL_TASKS_ARE_FP     FALSE
122
123/**
124 * Should the IDLE task have a floating point context?
125 *
126 * - If TRUE, then the IDLE task is created as a FLOATING_POINT task
127 *   and it has a floating point context which is switched in and out.
128 * - If FALSE, then the IDLE task does not have a floating point context.
129 *
130 * The IDLE task does not have to be floating point on the SPARC.
131 */
132#define CPU_IDLE_TASK_IS_FP      FALSE
133
134#define CPU_USE_DEFERRED_FP_SWITCH FALSE
135
136#define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
137
138/**
139 * Does the stack grow up (toward higher addresses) or down
140 * (toward lower addresses)?
141 *
142 * - If TRUE, then the grows upward.
143 * - If FALSE, then the grows toward smaller addresses.
144 *
145 * The stack grows to lower addresses on the SPARC.
146 */
147#define CPU_STACK_GROWS_UP               FALSE
148
149/* LEON3 systems may use a cache line size of 64 */
150#define CPU_CACHE_LINE_BYTES 64
151
152#define CPU_STRUCTURE_ALIGNMENT RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES )
153
154/**
155 * The following defines the number of bits actually used in the
156 * interrupt field of the task mode.  How those bits map to the
157 * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
158 *
159 * The SPARC has 16 interrupt levels in the PIL field of the PSR.
160 */
161#define CPU_MODES_INTERRUPT_MASK   0x0000000F
162
163#ifndef ASM
164/**
165 * This structure represents the organization of the minimum stack frame
166 * for the SPARC.  More framing information is required in certain situaions
167 * such as when there are a large number of out parameters or when the callee
168 * must save floating point registers.
169 */
170typedef struct {
171  /** This is the offset of the l0 register. */
172  uint32_t    l0;
173  /** This is the offset of the l1 register. */
174  uint32_t    l1;
175  /** This is the offset of the l2 register. */
176  uint32_t    l2;
177  /** This is the offset of the l3 register. */
178  uint32_t    l3;
179  /** This is the offset of the l4 register. */
180  uint32_t    l4;
181  /** This is the offset of the l5 register. */
182  uint32_t    l5;
183  /** This is the offset of the l6 register. */
184  uint32_t    l6;
185  /** This is the offset of the l7 register. */
186  uint32_t    l7;
187  /** This is the offset of the l0 register. */
188  uint32_t    i0;
189  /** This is the offset of the i1 register. */
190  uint32_t    i1;
191  /** This is the offset of the i2 register. */
192  uint32_t    i2;
193  /** This is the offset of the i3 register. */
194  uint32_t    i3;
195  /** This is the offset of the i4 register. */
196  uint32_t    i4;
197  /** This is the offset of the i5 register. */
198  uint32_t    i5;
199  /** This is the offset of the i6 register. */
200  uint32_t    i6_fp;
201  /** This is the offset of the i7 register. */
202  uint32_t    i7;
203  /** This is the offset of the register used to return structures. */
204  void       *structure_return_address;
205
206  /*
207   * The following are for the callee to save the register arguments in
208   * should this be necessary.
209   */
210  /** This is the offset of the register for saved argument 0. */
211  uint32_t    saved_arg0;
212  /** This is the offset of the register for saved argument 1. */
213  uint32_t    saved_arg1;
214  /** This is the offset of the register for saved argument 2. */
215  uint32_t    saved_arg2;
216  /** This is the offset of the register for saved argument 3. */
217  uint32_t    saved_arg3;
218  /** This is the offset of the register for saved argument 4. */
219  uint32_t    saved_arg4;
220  /** This is the offset of the register for saved argument 5. */
221  uint32_t    saved_arg5;
222  /** This field pads the structure so ldd and std instructions can be used. */
223  uint32_t    pad0;
224} SPARC_Minimum_stack_frame;
225
226#endif /* ASM */
227
228/** This macro defines an offset into the stack frame for use in assembly. */
229#define CPU_STACK_FRAME_L0_OFFSET             0x00
230/** This macro defines an offset into the stack frame for use in assembly. */
231#define CPU_STACK_FRAME_L1_OFFSET             0x04
232/** This macro defines an offset into the stack frame for use in assembly. */
233#define CPU_STACK_FRAME_L2_OFFSET             0x08
234/** This macro defines an offset into the stack frame for use in assembly. */
235#define CPU_STACK_FRAME_L3_OFFSET             0x0c
236/** This macro defines an offset into the stack frame for use in assembly. */
237#define CPU_STACK_FRAME_L4_OFFSET             0x10
238/** This macro defines an offset into the stack frame for use in assembly. */
239#define CPU_STACK_FRAME_L5_OFFSET             0x14
240/** This macro defines an offset into the stack frame for use in assembly. */
241#define CPU_STACK_FRAME_L6_OFFSET             0x18
242/** This macro defines an offset into the stack frame for use in assembly. */
243#define CPU_STACK_FRAME_L7_OFFSET             0x1c
244/** This macro defines an offset into the stack frame for use in assembly. */
245#define CPU_STACK_FRAME_I0_OFFSET             0x20
246/** This macro defines an offset into the stack frame for use in assembly. */
247#define CPU_STACK_FRAME_I1_OFFSET             0x24
248/** This macro defines an offset into the stack frame for use in assembly. */
249#define CPU_STACK_FRAME_I2_OFFSET             0x28
250/** This macro defines an offset into the stack frame for use in assembly. */
251#define CPU_STACK_FRAME_I3_OFFSET             0x2c
252/** This macro defines an offset into the stack frame for use in assembly. */
253#define CPU_STACK_FRAME_I4_OFFSET             0x30
254/** This macro defines an offset into the stack frame for use in assembly. */
255#define CPU_STACK_FRAME_I5_OFFSET             0x34
256/** This macro defines an offset into the stack frame for use in assembly. */
257#define CPU_STACK_FRAME_I6_FP_OFFSET          0x38
258/** This macro defines an offset into the stack frame for use in assembly. */
259#define CPU_STACK_FRAME_I7_OFFSET             0x3c
260/** This macro defines an offset into the stack frame for use in assembly. */
261#define CPU_STRUCTURE_RETURN_ADDRESS_OFFSET   0x40
262/** This macro defines an offset into the stack frame for use in assembly. */
263#define CPU_STACK_FRAME_SAVED_ARG0_OFFSET     0x44
264/** This macro defines an offset into the stack frame for use in assembly. */
265#define CPU_STACK_FRAME_SAVED_ARG1_OFFSET     0x48
266/** This macro defines an offset into the stack frame for use in assembly. */
267#define CPU_STACK_FRAME_SAVED_ARG2_OFFSET     0x4c
268/** This macro defines an offset into the stack frame for use in assembly. */
269#define CPU_STACK_FRAME_SAVED_ARG3_OFFSET     0x50
270/** This macro defines an offset into the stack frame for use in assembly. */
271#define CPU_STACK_FRAME_SAVED_ARG4_OFFSET     0x54
272/** This macro defines an offset into the stack frame for use in assembly. */
273#define CPU_STACK_FRAME_SAVED_ARG5_OFFSET     0x58
274/** This macro defines an offset into the stack frame for use in assembly. */
275#define CPU_STACK_FRAME_PAD0_OFFSET           0x5c
276
277#define CPU_MAXIMUM_PROCESSORS 32
278
279/**
280 * @defgroup RTEMSScoreCPUSPARCContext SPARC Context Structures
281 *
282 * @ingroup RTEMSScoreCPUSPARC
283 *
284 * Generally there are 2 types of context to save.
285 *    + Interrupt registers to save
286 *    + Task level registers to save
287 *
288 * This means we have the following 3 context items:
289 *    + task level context stuff::  Context_Control
290 *    + floating point task stuff:: Context_Control_fp
291 *    + special interrupt level context :: Context_Control_interrupt
292 *
293 * On the SPARC, we are relatively conservative in that we save most
294 * of the CPU state in the context area.  The ET (enable trap) bit and
295 * the CWP (current window pointer) fields of the PSR are considered
296 * system wide resources and are not maintained on a per-thread basis.
297 */
298/**@{**/
299
300#ifndef ASM
301typedef struct Context_Control_fp Context_Control_fp;
302
303/**
304 * @brief SPARC basic context.
305 *
306 * This structure defines the non-volatile integer and processor state context
307 * for the SPARC architecture according to "SYSTEM V APPLICATION BINARY
308 * INTERFACE - SPARC Processor Supplement", Third Edition.
309 *
310 * The registers g2 through g4 are reserved for applications.  GCC uses them as
311 * volatile registers by default.  So they are treated like volatile registers
312 * in RTEMS as well.
313 *
314 * The register g6 contains the per-CPU control of the current processor.  It
315 * is an invariant of the processor context.  This register must not be saved
316 * and restored during context switches or interrupt services.
317 */
318typedef struct {
319  /** This will contain the contents of the g5 register. */
320  uint32_t   g5;
321  /** This will contain the contents of the g7 register. */
322  uint32_t   g7;
323
324  /**
325   * This will contain the contents of the l0 and l1 registers.
326   *
327   * Using a double l0_and_l1 will put everything in this structure on a double
328   * word boundary which allows us to use double word loads and stores safely
329   * in the context switch.
330   */
331  double     l0_and_l1;
332  /** This will contain the contents of the l2 register. */
333  uint32_t   l2;
334  /** This will contain the contents of the l3 register. */
335  uint32_t   l3;
336  /** This will contain the contents of the l4 register. */
337  uint32_t   l4;
338  /** This will contain the contents of the l5 registeer.*/
339  uint32_t   l5;
340  /** This will contain the contents of the l6 register. */
341  uint32_t   l6;
342  /** This will contain the contents of the l7 register. */
343  uint32_t   l7;
344
345  /** This will contain the contents of the i0 register. */
346  uint32_t   i0;
347  /** This will contain the contents of the i1 register. */
348  uint32_t   i1;
349  /** This will contain the contents of the i2 register. */
350  uint32_t   i2;
351  /** This will contain the contents of the i3 register. */
352  uint32_t   i3;
353  /** This will contain the contents of the i4 register. */
354  uint32_t   i4;
355  /** This will contain the contents of the i5 register. */
356  uint32_t   i5;
357  /** This will contain the contents of the i6 (e.g. frame pointer) register. */
358  uint32_t   i6_fp;
359  /** This will contain the contents of the i7 register. */
360  uint32_t   i7;
361
362  /** This will contain the contents of the o6 (e.g. frame pointer) register. */
363  uint32_t   o6_sp;
364  /**
365   * This will contain the contents of the o7 (e.g. address of CALL
366   * instruction) register.
367   */
368  uint32_t   o7;
369
370  /** This will contain the contents of the processor status register. */
371  uint32_t   psr;
372  /**
373   * This field is used to prevent heavy nesting of calls to _Thread_Dispatch
374   * on an interrupted  task's stack.  This is problematic on the slower
375   * SPARC CPU models at high interrupt rates.
376   */
377  uint32_t   isr_dispatch_disable;
378
379#if defined(SPARC_USE_LAZY_FP_SWITCH)
380  Context_Control_fp *fp_context;
381#endif
382
383#if defined(RTEMS_SMP)
384  volatile uint32_t is_executing;
385#endif
386} Context_Control;
387
388/**
389 * This macro provides a CPU independent way for RTEMS to access the
390 * stack pointer in a context structure. The actual name and offset is
391 * CPU architecture dependent.
392 */
393#define _CPU_Context_Get_SP( _context ) \
394  (_context)->o6_sp
395
396#ifdef RTEMS_SMP
397  static inline bool _CPU_Context_Get_is_executing(
398    const Context_Control *context
399  )
400  {
401    return context->is_executing;
402  }
403
404  static inline void _CPU_Context_Set_is_executing(
405    Context_Control *context,
406    bool is_executing
407  )
408  {
409    context->is_executing = is_executing;
410  }
411#endif
412
413#endif /* ASM */
414
415/*
416 *  Offsets of fields with Context_Control for assembly routines.
417 */
418
419/** This macro defines an offset into the context for use in assembly. */
420#define G5_OFFSET    0x00
421/** This macro defines an offset into the context for use in assembly. */
422#define G7_OFFSET    0x04
423
424/** This macro defines an offset into the context for use in assembly. */
425#define L0_OFFSET    0x08
426/** This macro defines an offset into the context for use in assembly. */
427#define L1_OFFSET    0x0C
428/** This macro defines an offset into the context for use in assembly. */
429#define L2_OFFSET    0x10
430/** This macro defines an offset into the context for use in assembly. */
431#define L3_OFFSET    0x14
432/** This macro defines an offset into the context for use in assembly. */
433#define L4_OFFSET    0x18
434/** This macro defines an offset into the context for use in assembly. */
435#define L5_OFFSET    0x1C
436/** This macro defines an offset into the context for use in assembly. */
437#define L6_OFFSET    0x20
438/** This macro defines an offset into the context for use in assembly. */
439#define L7_OFFSET    0x24
440
441/** This macro defines an offset into the context for use in assembly. */
442#define I0_OFFSET    0x28
443/** This macro defines an offset into the context for use in assembly. */
444#define I1_OFFSET    0x2C
445/** This macro defines an offset into the context for use in assembly. */
446#define I2_OFFSET    0x30
447/** This macro defines an offset into the context for use in assembly. */
448#define I3_OFFSET    0x34
449/** This macro defines an offset into the context for use in assembly. */
450#define I4_OFFSET    0x38
451/** This macro defines an offset into the context for use in assembly. */
452#define I5_OFFSET    0x3C
453/** This macro defines an offset into the context for use in assembly. */
454#define I6_FP_OFFSET 0x40
455/** This macro defines an offset into the context for use in assembly. */
456#define I7_OFFSET    0x44
457
458/** This macro defines an offset into the context for use in assembly. */
459#define O6_SP_OFFSET 0x48
460/** This macro defines an offset into the context for use in assembly. */
461#define O7_OFFSET    0x4C
462
463/** This macro defines an offset into the context for use in assembly. */
464#define PSR_OFFSET   0x50
465/** This macro defines an offset into the context for use in assembly. */
466#define ISR_DISPATCH_DISABLE_STACK_OFFSET 0x54
467
468#if defined(RTEMS_SMP)
469  #define SPARC_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 0x58
470#endif
471
472#ifndef ASM
473/**
474 * @brief SPARC basic context.
475 *
476 * This structure defines floating point context area.
477 */
478struct Context_Control_fp {
479  /** This will contain the contents of the f0 and f1 register. */
480  double      f0_f1;
481  /** This will contain the contents of the f2 and f3 register. */
482  double      f2_f3;
483  /** This will contain the contents of the f4 and f5 register. */
484  double      f4_f5;
485  /** This will contain the contents of the f6 and f7 register. */
486  double      f6_f7;
487  /** This will contain the contents of the f8 and f9 register. */
488  double      f8_f9;
489  /** This will contain the contents of the f10 and f11 register. */
490  double      f10_f11;
491  /** This will contain the contents of the f12 and f13 register. */
492  double      f12_f13;
493  /** This will contain the contents of the f14 and f15 register. */
494  double      f14_f15;
495  /** This will contain the contents of the f16 and f17 register. */
496  double      f16_f17;
497  /** This will contain the contents of the f18 and f19 register. */
498  double      f18_f19;
499  /** This will contain the contents of the f20 and f21 register. */
500  double      f20_f21;
501  /** This will contain the contents of the f22 and f23 register. */
502  double      f22_f23;
503  /** This will contain the contents of the f24 and f25 register. */
504  double      f24_f25;
505  /** This will contain the contents of the f26 and f27 register. */
506  double      f26_f27;
507  /** This will contain the contents of the f28 and f29 register. */
508  double      f28_f29;
509  /** This will contain the contents of the f30 and f31 register. */
510  double      f30_f31;
511  /** This will contain the contents of the floating point status register. */
512  uint32_t    fsr;
513};
514
515#endif /* ASM */
516
517/*
518 *  Offsets of fields with Context_Control_fp for assembly routines.
519 */
520
521/** This macro defines an offset into the FPU context for use in assembly. */
522#define FO_F1_OFFSET     0x00
523/** This macro defines an offset into the FPU context for use in assembly. */
524#define F2_F3_OFFSET     0x08
525/** This macro defines an offset into the FPU context for use in assembly. */
526#define F4_F5_OFFSET     0x10
527/** This macro defines an offset into the FPU context for use in assembly. */
528#define F6_F7_OFFSET     0x18
529/** This macro defines an offset into the FPU context for use in assembly. */
530#define F8_F9_OFFSET     0x20
531/** This macro defines an offset into the FPU context for use in assembly. */
532#define F1O_F11_OFFSET   0x28
533/** This macro defines an offset into the FPU context for use in assembly. */
534#define F12_F13_OFFSET   0x30
535/** This macro defines an offset into the FPU context for use in assembly. */
536#define F14_F15_OFFSET   0x38
537/** This macro defines an offset into the FPU context for use in assembly. */
538#define F16_F17_OFFSET   0x40
539/** This macro defines an offset into the FPU context for use in assembly. */
540#define F18_F19_OFFSET   0x48
541/** This macro defines an offset into the FPU context for use in assembly. */
542#define F2O_F21_OFFSET   0x50
543/** This macro defines an offset into the FPU context for use in assembly. */
544#define F22_F23_OFFSET   0x58
545/** This macro defines an offset into the FPU context for use in assembly. */
546#define F24_F25_OFFSET   0x60
547/** This macro defines an offset into the FPU context for use in assembly. */
548#define F26_F27_OFFSET   0x68
549/** This macro defines an offset into the FPU context for use in assembly. */
550#define F28_F29_OFFSET   0x70
551/** This macro defines an offset into the FPU context for use in assembly. */
552#define F3O_F31_OFFSET   0x78
553/** This macro defines an offset into the FPU context for use in assembly. */
554#define FSR_OFFSET       0x80
555
556/** This defines the size of the FPU context area for use in assembly. */
557#define CONTEXT_CONTROL_FP_SIZE 0x84
558
559#ifndef ASM
560
561/** @} */
562
563/**
564 * @brief Interrupt stack frame (ISF).
565 *
566 * Context saved on stack for an interrupt.
567 *
568 * NOTE: The PSR, PC, and NPC are only saved in this structure for the
569 *       benefit of the user's handler.
570 */
571typedef struct {
572  /** On an interrupt, we must save the minimum stack frame. */
573  SPARC_Minimum_stack_frame Stack_frame;
574  /** This is the offset of the PSR on an ISF. */
575  uint32_t                 psr;
576  /** This is the offset of the XXX on an ISF. */
577  uint32_t                 pc;
578  /** This is the offset of the XXX on an ISF. */
579  uint32_t                 npc;
580  /** This is the offset of the g1 register on an ISF. */
581  uint32_t                 g1;
582  /** This is the offset of the g2 register on an ISF. */
583  uint32_t                 g2;
584  /** This is the offset of the g3 register on an ISF. */
585  uint32_t                 g3;
586  /** This is the offset of the g4 register on an ISF. */
587  uint32_t                 g4;
588  /** This is the offset of the g5 register on an ISF. */
589  uint32_t                 g5;
590  /** This is the offset is reserved for alignment on an ISF. */
591  uint32_t                 reserved_for_alignment;
592  /** This is the offset of the g7 register on an ISF. */
593  uint32_t                 g7;
594  /** This is the offset of the i0 register on an ISF. */
595  uint32_t                 i0;
596  /** This is the offset of the i1 register on an ISF. */
597  uint32_t                 i1;
598  /** This is the offset of the i2 register on an ISF. */
599  uint32_t                 i2;
600  /** This is the offset of the i3 register on an ISF. */
601  uint32_t                 i3;
602  /** This is the offset of the i4 register on an ISF. */
603  uint32_t                 i4;
604  /** This is the offset of the i5 register on an ISF. */
605  uint32_t                 i5;
606  /** This is the offset of the i6 register on an ISF. */
607  uint32_t                 i6_fp;
608  /** This is the offset of the i7 register on an ISF. */
609  uint32_t                 i7;
610  /** This is the offset of the y register on an ISF. */
611  uint32_t                 y;
612  /** This is the offset of the tpc register on an ISF. */
613  uint32_t                 tpc;
614} CPU_Interrupt_frame;
615
616#endif /* ASM */
617
618#ifndef ASM
619/**
620 * The following type defines an entry in the SPARC's trap table.
621 *
622 * NOTE: The instructions chosen are RTEMS dependent although one is
623 *       obligated to use two of the four instructions to perform a
624 *       long jump.  The other instructions load one register with the
625 *       trap type (a.k.a. vector) and another with the psr.
626 */
627typedef struct {
628  /** This will contain a "mov %psr, %l0" instruction. */
629  uint32_t     mov_psr_l0;
630  /** This will contain a "sethi %hi(_handler), %l4" instruction. */
631  uint32_t     sethi_of_handler_to_l4;
632  /** This will contain a "jmp %l4 + %lo(_handler)" instruction. */
633  uint32_t     jmp_to_low_of_handler_plus_l4;
634  /** This will contain a " mov _vector, %l3" instruction. */
635  uint32_t     mov_vector_l3;
636} CPU_Trap_table_entry;
637
638/**
639 * This is the set of opcodes for the instructions loaded into a trap
640 * table entry.  The routine which installs a handler is responsible
641 * for filling in the fields for the _handler address and the _vector
642 * trap type.
643 *
644 * The constants following this structure are masks for the fields which
645 * must be filled in when the handler is installed.
646 */
647extern const CPU_Trap_table_entry _CPU_Trap_slot_template;
648
649/**
650 * The size of the floating point context area.
651 */
652#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
653
654#endif
655
656/**
657 * Amount of extra stack (above minimum stack size) required by
658 * MPCI receive server thread.  Remember that in a multiprocessor
659 * system this thread must exist and be able to process all directives.
660 */
661#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 1024
662
663/**
664 * This defines the number of entries in the ISR_Vector_table managed
665 * by the executive.
666 *
667 * On the SPARC, there are really only 256 vectors.  However, the executive
668 * has no easy, fast, reliable way to determine which traps are synchronous
669 * and which are asynchronous.  By default, synchronous traps return to the
670 * instruction which caused the interrupt.  So if you install a software
671 * trap handler as an executive interrupt handler (which is desirable since
672 * RTEMS takes care of window and register issues), then the executive needs
673 * to know that the return address is to the trap rather than the instruction
674 * following the trap.
675 *
676 * So vectors 0 through 255 are treated as regular asynchronous traps which
677 * provide the "correct" return address.  Vectors 256 through 512 are assumed
678 * by the executive to be synchronous and to require that the return address
679 * be fudged.
680 *
681 * If you use this mechanism to install a trap handler which must reexecute
682 * the instruction which caused the trap, then it should be installed as
683 * an asynchronous trap.  This will avoid the executive changing the return
684 * address.
685 */
686#define CPU_INTERRUPT_NUMBER_OF_VECTORS     256
687
688/**
689 * The SPARC has 256 vectors but the port treats 256-512 as synchronous
690 * traps.
691 */
692#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER 511
693
694/**
695 * This is the bit step in a vector number to indicate it is being installed
696 * as a synchronous trap.
697 */
698#define SPARC_SYNCHRONOUS_TRAP_BIT_MASK     0x100
699
700/**
701 * This macro indicates that @a _trap as an asynchronous trap.
702 */
703#define SPARC_ASYNCHRONOUS_TRAP( _trap )    (_trap)
704
705/**
706 * This macro indicates that @a _trap as a synchronous trap.
707 */
708#define SPARC_SYNCHRONOUS_TRAP( _trap )     ((_trap) + 256 )
709
710/**
711 * This macro returns the real hardware vector number associated with @a _trap.
712 */
713#define SPARC_REAL_TRAP_NUMBER( _trap )     ((_trap) % 256)
714
715/**
716 * This is defined if the port has a special way to report the ISR nesting
717 * level.  Most ports maintain the variable _ISR_Nest_level.
718 */
719#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
720
721/**
722 * Should be large enough to run all tests.  This ensures
723 * that a "reasonable" small application should not have any problems.
724 *
725 * This appears to be a fairly generous number for the SPARC since
726 * represents a call depth of about 20 routines based on the minimum
727 * stack frame.
728 */
729#define CPU_STACK_MINIMUM_SIZE  (1024*4)
730
731/**
732 * What is the size of a pointer on this architecture?
733 */
734#define CPU_SIZEOF_POINTER 4
735
736/**
737 * CPU's worst alignment requirement for data types on a byte boundary.  This
738 * alignment does not take into account the requirements for the stack.
739 *
740 * On the SPARC, this is required for double word loads and stores.
741 */
742#define CPU_ALIGNMENT      8
743
744/**
745 * This number corresponds to the byte alignment requirement for the
746 * heap handler.  This alignment requirement may be stricter than that
747 * for the data types alignment specified by CPU_ALIGNMENT.  It is
748 * common for the heap to follow the same alignment requirement as
749 * CPU_ALIGNMENT.  If the CPU_ALIGNMENT is strict enough for the heap,
750 * then this should be set to CPU_ALIGNMENT.
751 *
752 * NOTE:  This does not have to be a power of 2.  It does have to
753 *        be greater or equal to than CPU_ALIGNMENT.
754 */
755#define CPU_HEAP_ALIGNMENT         CPU_ALIGNMENT
756
757/**
758 * Stack frames must be doubleword aligned according to the System V ABI for
759 * SPARC.
760 */
761#define CPU_STACK_ALIGNMENT CPU_ALIGNMENT
762
763#define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
764
765#ifndef ASM
766
767/*
768 *  ISR handler macros
769 */
770
771/**
772 * Support routine to initialize the RTEMS vector table after it is allocated.
773 */
774#define _CPU_Initialize_vectors()
775
776/**
777 * Disable all interrupts for a critical section.  The previous
778 * level is returned in _level.
779 */
780#define _CPU_ISR_Disable( _level ) \
781  (_level) = sparc_disable_interrupts()
782
783/**
784 * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
785 * This indicates the end of a critical section.  The parameter
786 * _level is not modified.
787 */
788#define _CPU_ISR_Enable( _level ) \
789  sparc_enable_interrupts( _level )
790
791/**
792 * This temporarily restores the interrupt to _level before immediately
793 * disabling them again.  This is used to divide long critical
794 * sections into two or more parts.  The parameter _level is not
795 * modified.
796 */
797#define _CPU_ISR_Flash( _level ) \
798  sparc_flash_interrupts( _level )
799
800#define _CPU_ISR_Is_enabled( _isr_cookie ) \
801  sparc_interrupt_is_enabled( _isr_cookie )
802
803RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level )
804{
805  return ( level & SPARC_PSR_PIL_MASK ) == 0;
806}
807
808/**
809 * Map interrupt level in task mode onto the hardware that the CPU
810 * actually provides.  Currently, interrupt levels which do not
811 * map onto the CPU in a straight fashion are undefined.
812 */
813#define _CPU_ISR_Set_level( _newlevel ) \
814   sparc_enable_interrupts( _newlevel << 8)
815
816/**
817 * @brief Obtain the current interrupt disable level.
818 *
819 * This method is invoked to return the current interrupt disable level.
820 *
821 * @return This method returns the current interrupt disable level.
822 */
823uint32_t   _CPU_ISR_Get_level( void );
824
825/* end of ISR handler macros */
826
827/* Context handler macros */
828
829/**
830 * Initialize the context to a state suitable for starting a
831 * task after a context restore operation.  Generally, this
832 * involves:
833 *
834 * - setting a starting address
835 * - preparing the stack
836 * - preparing the stack and frame pointers
837 * - setting the proper interrupt level in the context
838 * - initializing the floating point context
839 *
840 * @param[in] the_context points to the context area
841 * @param[in] stack_base is the low address of the allocated stack area
842 * @param[in] size is the size of the stack area in bytes
843 * @param[in] new_level is the interrupt level for the task
844 * @param[in] entry_point is the task's entry point
845 * @param[in] is_fp is set to TRUE if the task is a floating point task
846 * @param[in] tls_area is the thread-local storage (TLS) area
847 *
848 * NOTE:  Implemented as a subroutine for the SPARC port.
849 */
850void _CPU_Context_Initialize(
851  Context_Control  *the_context,
852  uint32_t         *stack_base,
853  uint32_t          size,
854  uint32_t          new_level,
855  void             *entry_point,
856  bool              is_fp,
857  void             *tls_area
858);
859
860/**
861 * This macro is invoked from _Thread_Handler to do whatever CPU
862 * specific magic is required that must be done in the context of
863 * the thread when it starts.
864 *
865 * On the SPARC, this is setting the frame pointer so GDB is happy.
866 * Make GDB stop unwinding at _Thread_Handler, previous register window
867 * Frame pointer is 0 and calling address must be a function with starting
868 * with a SAVE instruction. If return address is leaf-function (no SAVE)
869 * GDB will not look at prev reg window fp.
870 *
871 * _Thread_Handler is known to start with SAVE.
872 */
873#define _CPU_Context_Initialization_at_thread_begin() \
874  do { \
875    __asm__ volatile ("set _Thread_Handler,%%i7\n"::); \
876  } while (0)
877
878/**
879 * This routine is responsible for somehow restarting the currently
880 * executing task.
881 *
882 * On the SPARC, this is is relatively painless but requires a small
883 * amount of wrapper code before using the regular restore code in
884 * of the context switch.
885 */
886#define _CPU_Context_Restart_self( _the_context ) \
887   _CPU_Context_restore( (_the_context) );
888
889/**
890 * @brief Nothing to do due to the synchronous or lazy floating point switch.
891 */
892#define _CPU_Context_Initialize_fp( _destination ) \
893  do { } while ( 0 )
894
895/**
896 * @brief Nothing to do due to the synchronous or lazy floating point switch.
897 */
898#define _CPU_Context_save_fp( _fp_context_ptr ) \
899  do { } while ( 0 )
900
901/**
902 * @brief Nothing to do due to the synchronous or lazy floating point switch.
903 */
904#define _CPU_Context_restore_fp( _fp_context_ptr ) \
905  do { } while ( 0 )
906/* end of Context handler macros */
907
908/* Fatal Error manager macros */
909
910/**
911 * This routine copies _error into a known place -- typically a stack
912 * location or a register, optionally disables interrupts, and
913 * halts/stops the CPU.
914 */
915RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, uint32_t error );
916
917/* end of Fatal Error manager macros */
918
919#define CPU_USE_LIBC_INIT_FINI_ARRAY FALSE
920
921/* Bitfield handler macros */
922
923#if ( SPARC_HAS_BITSCAN == 0 )
924  /**
925   * The SPARC port uses the generic C algorithm for bitfield scan if the
926   * CPU model does not have a scan instruction.
927   */
928  #define CPU_USE_GENERIC_BITFIELD_CODE TRUE
929#else
930  #error "scan instruction not currently supported by RTEMS!!"
931#endif
932
933/* end of Bitfield handler macros */
934
935/* functions */
936
937/**
938 * @brief SPARC specific initialization.
939 *
940 * This routine performs CPU dependent initialization.
941 */
942void _CPU_Initialize(void);
943
944typedef void ( *CPU_ISR_raw_handler )( void );
945
946/**
947 * @brief SPARC specific raw ISR installer.
948 *
949 * This routine installs @a new_handler to be directly called from the trap
950 * table.
951 *
952 * @param[in] vector is the vector number
953 * @param[in] new_handler is the new ISR handler
954 * @param[in] old_handler will contain the old ISR handler
955 */
956void _CPU_ISR_install_raw_handler(
957  uint32_t             vector,
958  CPU_ISR_raw_handler  new_handler,
959  CPU_ISR_raw_handler *old_handler
960);
961
962typedef void ( *CPU_ISR_handler )( uint32_t );
963
964/**
965 * @brief SPARC specific RTEMS ISR installer.
966 *
967 * This routine installs an interrupt vector.
968 *
969 * @param[in] vector is the vector number
970 * @param[in] new_handler is the new ISR handler
971 * @param[in] old_handler will contain the old ISR handler
972 */
973
974void _CPU_ISR_install_vector(
975  uint32_t         vector,
976  CPU_ISR_handler  new_handler,
977  CPU_ISR_handler *old_handler
978);
979
980void *_CPU_Thread_Idle_body( uintptr_t ignored );
981
982/**
983 * @brief SPARC specific context switch.
984 *
985 * This routine switches from the run context to the heir context.
986 *
987 * @param[in] run is the currently executing thread
988 * @param[in] heir will become the currently executing thread
989 */
990void _CPU_Context_switch(
991  Context_Control  *run,
992  Context_Control  *heir
993);
994
995/**
996 * @brief SPARC specific context restore.
997 *
998 * This routine is generally used only to restart self in an
999 * efficient manner.
1000 *
1001 * @param[in] new_context is the context to restore
1002 */
1003RTEMS_NO_RETURN void _CPU_Context_restore( Context_Control *new_context );
1004
1005#if defined(RTEMS_SMP)
1006  uint32_t _CPU_SMP_Initialize( void );
1007
1008  bool _CPU_SMP_Start_processor( uint32_t cpu_index );
1009
1010  void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
1011
1012  void _CPU_SMP_Prepare_start_multitasking( void );
1013
1014  #if defined(__leon__) && !defined(RTEMS_PARAVIRT)
1015    static inline uint32_t _CPU_SMP_Get_current_processor( void )
1016    {
1017      return _LEON3_Get_current_processor();
1018    }
1019  #else
1020    uint32_t _CPU_SMP_Get_current_processor( void );
1021  #endif
1022
1023  void _CPU_SMP_Send_interrupt( uint32_t target_processor_index );
1024
1025  static inline void _CPU_SMP_Processor_event_broadcast( void )
1026  {
1027    __asm__ volatile ( "" : : : "memory" );
1028  }
1029
1030  static inline void _CPU_SMP_Processor_event_receive( void )
1031  {
1032    __asm__ volatile ( "" : : : "memory" );
1033  }
1034#endif
1035
1036#if defined(SPARC_USE_LAZY_FP_SWITCH)
1037#define _CPU_Context_Destroy( _the_thread, _the_context ) \
1038  do { \
1039    Per_CPU_Control *cpu_self = _Per_CPU_Get(); \
1040    Thread_Control *_fp_owner = cpu_self->cpu_per_cpu.fp_owner; \
1041    if ( _fp_owner == _the_thread ) { \
1042      cpu_self->cpu_per_cpu.fp_owner = NULL; \
1043    } \
1044  } while ( 0 )
1045#endif
1046
1047typedef struct {
1048  uint32_t trap;
1049  CPU_Interrupt_frame *isf;
1050} CPU_Exception_frame;
1051
1052void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
1053
1054/**
1055 * @brief SPARC specific method to endian swap an uint32_t.
1056 *
1057 * The following routine swaps the endian format of an unsigned int.
1058 * It must be static because it is referenced indirectly.
1059 *
1060 * @param[in] value is the value to endian swap
1061 *
1062 * This version will work on any processor, but if you come across a better
1063 * way for the SPARC PLEASE use it.  The most common way to swap a 32-bit
1064 * entity as shown below is not any more efficient on the SPARC.
1065 *
1066 *    - swap least significant two bytes with 16-bit rotate
1067 *    - swap upper and lower 16-bits
1068 *    - swap most significant two bytes with 16-bit rotate
1069 *
1070 * It is not obvious how the SPARC can do significantly better than the
1071 * generic code.  gcc 2.7.0 only generates about 12 instructions for the
1072 * following code at optimization level four (i.e. -O4).
1073 */
1074static inline uint32_t CPU_swap_u32(
1075  uint32_t value
1076)
1077{
1078  uint32_t   byte1, byte2, byte3, byte4, swapped;
1079
1080  byte4 = (value >> 24) & 0xff;
1081  byte3 = (value >> 16) & 0xff;
1082  byte2 = (value >> 8)  & 0xff;
1083  byte1 =  value        & 0xff;
1084
1085  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
1086  return( swapped );
1087}
1088
1089/**
1090 * @brief SPARC specific method to endian swap an uint16_t.
1091 *
1092 * The following routine swaps the endian format of a uint16_t.
1093 *
1094 * @param[in] value is the value to endian swap
1095 */
1096#define CPU_swap_u16( value ) \
1097  (((value&0xff) << 8) | ((value >> 8)&0xff))
1098
1099typedef uint32_t CPU_Counter_ticks;
1100
1101uint32_t _CPU_Counter_frequency( void );
1102
1103typedef CPU_Counter_ticks ( *SPARC_Counter_read )( void );
1104
1105/*
1106 * The SPARC processors supported by RTEMS have no built-in CPU counter
1107 * support.  We have to use some hardware counter module for this purpose, for
1108 * example the GPTIMER instance used by the clock driver.  The BSP must provide
1109 * an implementation of the CPU counter read function.  This allows the use of
1110 * dynamic hardware enumeration.
1111 */
1112typedef struct {
1113  SPARC_Counter_read                read_isr_disabled;
1114  SPARC_Counter_read                read;
1115  volatile const CPU_Counter_ticks *counter_register;
1116  volatile const uint32_t          *pending_register;
1117  uint32_t                          pending_mask;
1118  CPU_Counter_ticks                 accumulated;
1119  CPU_Counter_ticks                 interval;
1120} SPARC_Counter;
1121
1122extern const SPARC_Counter _SPARC_Counter;
1123
1124static inline CPU_Counter_ticks _CPU_Counter_read( void )
1125{
1126  return ( *_SPARC_Counter.read )();
1127}
1128
1129static inline CPU_Counter_ticks _CPU_Counter_difference(
1130  CPU_Counter_ticks second,
1131  CPU_Counter_ticks first
1132)
1133{
1134  return second - first;
1135}
1136
1137/** Type that can store a 32-bit integer or a pointer. */
1138typedef uintptr_t CPU_Uint32ptr;
1139
1140#endif /* ASM */
1141
1142#ifdef __cplusplus
1143}
1144#endif
1145
1146#endif
Note: See TracBrowser for help on using the repository browser.