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

5
Last change on this file since 25afa79 was 25afa79, checked in by Andreas Dachsberger <andreas.dachsberger@…>, on 03/27/19 at 09:50:44

doxygen: score: Add SPARC CPU architecture group

Update #3706.

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