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

Last change on this file since 4adaed73 was 4adaed73, checked in by Sebastian Huber <sebastian.huber@…>, on 07/27/21 at 09:08:54

score: Remove processor event broadcast/receive

Remove _CPU_SMP_Processor_event_broadcast() and
_CPU_SMP_Processor_event_receive(). These functions are hard to use since they
are subject to the lost wake up problem.

  • Property mode set to 100644
File size: 39.3 KB
Line 
1/**
2 * @file
3 *
4 * @brief SPARC CPU Department Source
5 *
6 * This include file contains information pertaining to the port of
7 * the executive to the SPARC processor.
8 */
9
10/*
11 *  COPYRIGHT (c) 1989-2011.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#ifndef _RTEMS_SCORE_CPU_H
20#define _RTEMS_SCORE_CPU_H
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26#include <rtems/score/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 defined if the port has a special way to report the ISR nesting
696 * level.  Most ports maintain the variable _ISR_Nest_level.
697 */
698#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
699
700/**
701 * Should be large enough to run all tests.  This ensures
702 * that a "reasonable" small application should not have any problems.
703 *
704 * This appears to be a fairly generous number for the SPARC since
705 * represents a call depth of about 20 routines based on the minimum
706 * stack frame.
707 */
708#define CPU_STACK_MINIMUM_SIZE  (1024*4)
709
710/**
711 * What is the size of a pointer on this architecture?
712 */
713#define CPU_SIZEOF_POINTER 4
714
715/**
716 * CPU's worst alignment requirement for data types on a byte boundary.  This
717 * alignment does not take into account the requirements for the stack.
718 *
719 * On the SPARC, this is required for double word loads and stores.
720 */
721#define CPU_ALIGNMENT      8
722
723/**
724 * This number corresponds to the byte alignment requirement for the
725 * heap handler.  This alignment requirement may be stricter than that
726 * for the data types alignment specified by CPU_ALIGNMENT.  It is
727 * common for the heap to follow the same alignment requirement as
728 * CPU_ALIGNMENT.  If the CPU_ALIGNMENT is strict enough for the heap,
729 * then this should be set to CPU_ALIGNMENT.
730 *
731 * NOTE:  This does not have to be a power of 2.  It does have to
732 *        be greater or equal to than CPU_ALIGNMENT.
733 */
734#define CPU_HEAP_ALIGNMENT         CPU_ALIGNMENT
735
736/**
737 * Stack frames must be doubleword aligned according to the System V ABI for
738 * SPARC.
739 */
740#define CPU_STACK_ALIGNMENT CPU_ALIGNMENT
741
742#define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
743
744#ifndef ASM
745
746/**
747 * @brief Dispatches the installed interrupt handlers.
748 *
749 * @param irq is the interrupt vector number of the external interrupt ranging
750 *   from 0 to 15.  This is not a trap number.
751 */
752void _SPARC_Interrupt_dispatch( uint32_t irq );
753
754/**
755 * Disable all interrupts for a critical section.  The previous
756 * level is returned in _level.
757 */
758#define _CPU_ISR_Disable( _level ) \
759  (_level) = sparc_disable_interrupts()
760
761/**
762 * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
763 * This indicates the end of a critical section.  The parameter
764 * _level is not modified.
765 */
766#define _CPU_ISR_Enable( _level ) \
767  sparc_enable_interrupts( _level )
768
769/**
770 * This temporarily restores the interrupt to _level before immediately
771 * disabling them again.  This is used to divide long critical
772 * sections into two or more parts.  The parameter _level is not
773 * modified.
774 */
775#define _CPU_ISR_Flash( _level ) \
776  sparc_flash_interrupts( _level )
777
778#define _CPU_ISR_Is_enabled( _isr_cookie ) \
779  sparc_interrupt_is_enabled( _isr_cookie )
780
781RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level )
782{
783  return ( level & SPARC_PSR_PIL_MASK ) == 0;
784}
785
786/**
787 * Map interrupt level in task mode onto the hardware that the CPU
788 * actually provides.  Currently, interrupt levels which do not
789 * map onto the CPU in a straight fashion are undefined.
790 */
791#define _CPU_ISR_Set_level( _newlevel ) \
792   sparc_enable_interrupts( _newlevel << 8)
793
794/**
795 * @brief Obtain the current interrupt disable level.
796 *
797 * This method is invoked to return the current interrupt disable level.
798 *
799 * @return This method returns the current interrupt disable level.
800 */
801uint32_t   _CPU_ISR_Get_level( void );
802
803/* end of ISR handler macros */
804
805/* Context handler macros */
806
807/**
808 * Initialize the context to a state suitable for starting a
809 * task after a context restore operation.  Generally, this
810 * involves:
811 *
812 * - setting a starting address
813 * - preparing the stack
814 * - preparing the stack and frame pointers
815 * - setting the proper interrupt level in the context
816 * - initializing the floating point context
817 *
818 * @param[in] the_context points to the context area
819 * @param[in] stack_base is the low address of the allocated stack area
820 * @param[in] size is the size of the stack area in bytes
821 * @param[in] new_level is the interrupt level for the task
822 * @param[in] entry_point is the task's entry point
823 * @param[in] is_fp is set to TRUE if the task is a floating point task
824 * @param[in] tls_area is the thread-local storage (TLS) area
825 *
826 * NOTE:  Implemented as a subroutine for the SPARC port.
827 */
828void _CPU_Context_Initialize(
829  Context_Control  *the_context,
830  uint32_t         *stack_base,
831  uint32_t          size,
832  uint32_t          new_level,
833  void             *entry_point,
834  bool              is_fp,
835  void             *tls_area
836);
837
838/**
839 * This macro is invoked from _Thread_Handler to do whatever CPU
840 * specific magic is required that must be done in the context of
841 * the thread when it starts.
842 *
843 * On the SPARC, this is setting the frame pointer so GDB is happy.
844 * Make GDB stop unwinding at _Thread_Handler, previous register window
845 * Frame pointer is 0 and calling address must be a function with starting
846 * with a SAVE instruction. If return address is leaf-function (no SAVE)
847 * GDB will not look at prev reg window fp.
848 *
849 * _Thread_Handler is known to start with SAVE.
850 */
851#define _CPU_Context_Initialization_at_thread_begin() \
852  do { \
853    __asm__ volatile ("set _Thread_Handler,%%i7\n"::); \
854  } while (0)
855
856/**
857 * This routine is responsible for somehow restarting the currently
858 * executing task.
859 *
860 * On the SPARC, this is is relatively painless but requires a small
861 * amount of wrapper code before using the regular restore code in
862 * of the context switch.
863 */
864#define _CPU_Context_Restart_self( _the_context ) \
865   _CPU_Context_restore( (_the_context) );
866
867/**
868 * @brief Nothing to do due to the synchronous or lazy floating point switch.
869 */
870#define _CPU_Context_Initialize_fp( _destination ) \
871  do { } while ( 0 )
872
873/**
874 * @brief Nothing to do due to the synchronous or lazy floating point switch.
875 */
876#define _CPU_Context_save_fp( _fp_context_ptr ) \
877  do { } while ( 0 )
878
879/**
880 * @brief Nothing to do due to the synchronous or lazy floating point switch.
881 */
882#define _CPU_Context_restore_fp( _fp_context_ptr ) \
883  do { } while ( 0 )
884/* end of Context handler macros */
885
886/* Fatal Error manager macros */
887
888/**
889 * This routine copies _error into a known place -- typically a stack
890 * location or a register, optionally disables interrupts, and
891 * halts/stops the CPU.
892 */
893RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, uint32_t error );
894
895/* end of Fatal Error manager macros */
896
897#define CPU_USE_LIBC_INIT_FINI_ARRAY FALSE
898
899/* Bitfield handler macros */
900
901#if ( SPARC_HAS_BITSCAN == 0 )
902  /**
903   * The SPARC port uses the generic C algorithm for bitfield scan if the
904   * CPU model does not have a scan instruction.
905   */
906  #define CPU_USE_GENERIC_BITFIELD_CODE TRUE
907#else
908  #error "scan instruction not currently supported by RTEMS!!"
909#endif
910
911/* end of Bitfield handler macros */
912
913/* functions */
914
915/**
916 * @brief SPARC specific initialization.
917 *
918 * This routine performs CPU dependent initialization.
919 */
920void _CPU_Initialize(void);
921
922typedef void ( *CPU_ISR_raw_handler )( void );
923
924/**
925 * @brief SPARC specific raw ISR installer.
926 *
927 * This routine installs @a new_handler to be directly called from the trap
928 * table.
929 *
930 * @param[in] vector is the vector number
931 * @param[in] new_handler is the new ISR handler
932 * @param[in] old_handler will contain the old ISR handler
933 */
934void _CPU_ISR_install_raw_handler(
935  uint32_t             vector,
936  CPU_ISR_raw_handler  new_handler,
937  CPU_ISR_raw_handler *old_handler
938);
939
940typedef void ( *CPU_ISR_handler )( uint32_t );
941
942/**
943 * @brief SPARC specific RTEMS ISR installer.
944 *
945 * This routine installs an interrupt vector.
946 *
947 * @param[in] vector is the vector number
948 * @param[in] new_handler is the new ISR handler
949 * @param[in] old_handler will contain the old ISR handler
950 */
951
952void _CPU_ISR_install_vector(
953  uint32_t         vector,
954  CPU_ISR_handler  new_handler,
955  CPU_ISR_handler *old_handler
956);
957
958void *_CPU_Thread_Idle_body( uintptr_t ignored );
959
960/**
961 * @brief SPARC specific context switch.
962 *
963 * This routine switches from the run context to the heir context.
964 *
965 * @param[in] run is the currently executing thread
966 * @param[in] heir will become the currently executing thread
967 */
968void _CPU_Context_switch(
969  Context_Control  *run,
970  Context_Control  *heir
971);
972
973RTEMS_NO_RETURN void _CPU_Context_switch_no_return(
974  Context_Control *executing,
975  Context_Control *heir
976);
977
978/**
979 * @brief SPARC specific context restore.
980 *
981 * This routine is generally used only to restart self in an
982 * efficient manner.
983 *
984 * @param[in] new_context is the context to restore
985 */
986RTEMS_NO_RETURN void _CPU_Context_restore( Context_Control *new_context );
987
988#if defined(RTEMS_SMP)
989  uint32_t _CPU_SMP_Initialize( void );
990
991  bool _CPU_SMP_Start_processor( uint32_t cpu_index );
992
993  void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
994
995  void _CPU_SMP_Prepare_start_multitasking( void );
996
997  #if defined(__leon__) && !defined(RTEMS_PARAVIRT)
998    static inline uint32_t _CPU_SMP_Get_current_processor( void )
999    {
1000      return _LEON3_Get_current_processor();
1001    }
1002  #else
1003    uint32_t _CPU_SMP_Get_current_processor( void );
1004  #endif
1005
1006  void _CPU_SMP_Send_interrupt( uint32_t target_processor_index );
1007#endif
1008
1009#if defined(SPARC_USE_LAZY_FP_SWITCH)
1010#define _CPU_Context_Destroy( _the_thread, _the_context ) \
1011  do { \
1012    Per_CPU_Control *cpu_self = _Per_CPU_Get(); \
1013    Thread_Control *_fp_owner = cpu_self->cpu_per_cpu.fp_owner; \
1014    if ( _fp_owner == _the_thread ) { \
1015      cpu_self->cpu_per_cpu.fp_owner = NULL; \
1016    } \
1017  } while ( 0 )
1018#endif
1019
1020/**
1021 * @brief This structure contains the local and input registers of a register
1022 *   window.
1023 */
1024typedef struct {
1025  /** @brief This member contains the local 0..7 register values. */
1026  uint32_t local[ 8 ];
1027
1028  /** @brief This member contains the input 0..7 register values. */
1029  uint32_t input[ 8 ];
1030} SPARC_Register_window;
1031
1032/**
1033 * @brief This structure contains the register set of a context which caused an
1034 *   unexpected trap.
1035 */
1036typedef struct {
1037  /** @brief This member contains the PSR register value. */
1038  uint32_t psr;
1039
1040  /** @brief This member contains the PC value. */
1041  uint32_t pc;
1042
1043  /** @brief This member contains the nPC value. */
1044  uint32_t npc;
1045
1046  /** @brief This member contains the trap number. */
1047  uint32_t trap;
1048
1049  /** @brief This member contains the WIM register value. */
1050  uint32_t wim;
1051
1052  /** @brief This member contains the Y register value. */
1053  uint32_t y;
1054
1055  /** @brief This member contains the global 0..7 register values. */
1056  uint32_t global[ 8 ];
1057
1058  /** @brief This member contains the output 0..7 register values. */
1059  uint32_t output[ 8 ] ;
1060
1061  /**
1062   * @brief This member contains the additional register windows according to
1063   *   the saved WIM.
1064   */
1065  SPARC_Register_window windows[ SPARC_NUMBER_OF_REGISTER_WINDOWS - 1 ];
1066
1067#if SPARC_HAS_FPU == 1
1068  /** This member contain the FSR register value. */
1069  uint32_t fsr;
1070
1071  /** @brief This member contains the floating point 0..31 register values. */
1072  uint64_t fp[ 16 ];
1073#endif
1074} CPU_Exception_frame;
1075
1076void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
1077
1078/**
1079 * @brief SPARC specific method to endian swap an uint32_t.
1080 *
1081 * The following routine swaps the endian format of an unsigned int.
1082 * It must be static because it is referenced indirectly.
1083 *
1084 * @param[in] value is the value to endian swap
1085 *
1086 * This version will work on any processor, but if you come across a better
1087 * way for the SPARC PLEASE use it.  The most common way to swap a 32-bit
1088 * entity as shown below is not any more efficient on the SPARC.
1089 *
1090 *    - swap least significant two bytes with 16-bit rotate
1091 *    - swap upper and lower 16-bits
1092 *    - swap most significant two bytes with 16-bit rotate
1093 *
1094 * It is not obvious how the SPARC can do significantly better than the
1095 * generic code.  gcc 2.7.0 only generates about 12 instructions for the
1096 * following code at optimization level four (i.e. -O4).
1097 */
1098static inline uint32_t CPU_swap_u32(
1099  uint32_t value
1100)
1101{
1102  uint32_t   byte1, byte2, byte3, byte4, swapped;
1103
1104  byte4 = (value >> 24) & 0xff;
1105  byte3 = (value >> 16) & 0xff;
1106  byte2 = (value >> 8)  & 0xff;
1107  byte1 =  value        & 0xff;
1108
1109  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
1110  return( swapped );
1111}
1112
1113/**
1114 * @brief SPARC specific method to endian swap an uint16_t.
1115 *
1116 * The following routine swaps the endian format of a uint16_t.
1117 *
1118 * @param[in] value is the value to endian swap
1119 */
1120#define CPU_swap_u16( value ) \
1121  (((value&0xff) << 8) | ((value >> 8)&0xff))
1122
1123typedef uint32_t CPU_Counter_ticks;
1124
1125uint32_t _CPU_Counter_frequency( void );
1126
1127typedef CPU_Counter_ticks ( *SPARC_Counter_read )( void );
1128
1129/*
1130 * The SPARC processors supported by RTEMS have no built-in CPU counter
1131 * support.  We have to use some hardware counter module for this purpose, for
1132 * example the GPTIMER instance used by the clock driver.  The BSP must provide
1133 * an implementation of the CPU counter read function.  This allows the use of
1134 * dynamic hardware enumeration.
1135 */
1136typedef struct {
1137  SPARC_Counter_read                read_isr_disabled;
1138  SPARC_Counter_read                read;
1139  volatile const CPU_Counter_ticks *counter_register;
1140  volatile const uint32_t          *pending_register;
1141  uint32_t                          pending_mask;
1142  CPU_Counter_ticks                 accumulated;
1143  CPU_Counter_ticks                 interval;
1144} SPARC_Counter;
1145
1146extern const SPARC_Counter _SPARC_Counter;
1147
1148static inline CPU_Counter_ticks _CPU_Counter_read( void )
1149{
1150  return ( *_SPARC_Counter.read )();
1151}
1152
1153static inline CPU_Counter_ticks _CPU_Counter_difference(
1154  CPU_Counter_ticks second,
1155  CPU_Counter_ticks first
1156)
1157{
1158  return second - first;
1159}
1160
1161/** Type that can store a 32-bit integer or a pointer. */
1162typedef uintptr_t CPU_Uint32ptr;
1163
1164#endif /* ASM */
1165
1166#ifdef __cplusplus
1167}
1168#endif
1169
1170#endif
Note: See TracBrowser for help on using the repository browser.