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

5
Last change on this file since 55e76c2 was 2afb22b, checked in by Chris Johns <chrisj@…>, on 12/23/17 at 07:18:56

Remove make preinstall

A speciality of the RTEMS build system was the make preinstall step. It
copied header files from arbitrary locations into the build tree. The
header files were included via the -Bsome/build/tree/path GCC command
line option.

This has at least seven problems:

  • The make preinstall step itself needs time and disk space.
  • Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error.
  • There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult.
  • The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit.
  • An introduction of a new build system is difficult.
  • Include paths specified by the -B option are system headers. This may suppress warnings.
  • The parallel build had sporadic failures on some hosts.

This patch removes the make preinstall step. All installed header
files are moved to dedicated include directories in the source tree.
Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc,
etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g.
erc32, imx, qoriq, etc.

The new cpukit include directories are:

  • cpukit/include
  • cpukit/score/cpu/@RTEMS_CPU@/include
  • cpukit/libnetworking

The new BSP include directories are:

  • bsps/include
  • bsps/@RTEMS_CPU@/include
  • bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include

There are build tree include directories for generated files.

The include directory order favours the most general header file, e.g.
it is not possible to override general header files via the include path
order.

The "bootstrap -p" option was removed. The new "bootstrap -H" option
should be used to regenerate the "headers.am" files.

Update #3254.

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