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

4.115
Last change on this file since a51b352 was a51b352, checked in by Sebastian Huber <sebastian.huber@…>, on 05/30/15 at 15:48:27

sparc: Add SPARC_USE_SAFE_FP_SUPPORT

The SPARC ABI is a bit special with respect to the floating point context.
The complete floating point context is volatile. Thus from an ABI point
of view nothing needs to be saved and restored during a context switch.
Instead the floating point context must be saved and restored during
interrupt processing. Historically the deferred floating point switch is
used for SPARC and the complete floating point context is saved and
restored during a context switch to the new floating point unit owner.
This is a bit dangerous since post-switch actions (e.g. signal handlers)
and context switch extensions may silently corrupt the floating point
context. The floating point unit is disabled for interrupt handlers.
Thus in case an interrupt handler uses the floating point unit then this
will result in a trap.

On SMP configurations the deferred floating point switch is not
supported in principle. So use here a safe floating point support. Safe
means that the volatile floating point context is saved and restored
around a thread dispatch issued during interrupt processing. Thus
post-switch actions and context switch extensions may safely use the
floating point unit.

Update #2270.

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