source: rtems/cpukit/score/cpu/sparc/rtems/score/cpu.h @ 8df1f408

4.115
Last change on this file since 8df1f408 was 8df1f408, checked in by Christian Mauderer <Christian.Mauderer@…>, on 06/02/14 at 14:31:51

score/sparc: Add support for paravirtualization

Guest systems in paravirtualization environments run usually in user
mode. Thus it is not possible to directly access the PSR and TBR
registers. Use functions instead of inline assembler to access these
registers if RTEMS_PARAVIRT is defined.

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