source: rtems/cpukit/score/cpu/sparc/include/rtems/score/cpu.h @ 511dc4b

5
Last change on this file since 511dc4b was 511dc4b, checked in by Sebastian Huber <sebastian.huber@…>, on 06/19/18 at 07:09:51

Rework initialization and interrupt stack support

Statically initialize the interrupt stack area
(_Configuration_Interrupt_stack_area_begin,
_Configuration_Interrupt_stack_area_end, and
_Configuration_Interrupt_stack_size) via <rtems/confdefs.h>. Place the
interrupt stack area in a special section ".rtemsstack.interrupt". Let
BSPs define the optimal placement of this section in their linker
command files (e.g. in a fast on-chip memory).

This change makes makes the CPU_HAS_SOFTWARE_INTERRUPT_STACK and
CPU_HAS_HARDWARE_INTERRUPT_STACK CPU port defines superfluous, since the
low level initialization code has all information available via global
symbols.

This change makes the CPU_ALLOCATE_INTERRUPT_STACK CPU port define
superfluous, since the interrupt stacks are allocated by confdefs.h for
all architectures. There is no need for BSP-specific linker command
file magic (except the section placement), see previous ARM linker
command file as a bad example.

Remove _CPU_Install_interrupt_stack(). Initialize the hardware
interrupt stack in _CPU_Initialize() if necessary (e.g.
m68k_install_interrupt_stack()).

The optional _CPU_Interrupt_stack_setup() is still useful to customize
the registration of the interrupt stack area in the per-CPU information.

The initialization stack can reuse the interrupt stack, since

  • interrupts are disabled during the sequential system initialization, and
  • the boot_card() function does not return.

This stack resuse saves memory.

Changes per architecture:

arm:

  • Mostly replace the linker symbol based configuration of stacks with the standard <rtems/confdefs.h> configuration via CONFIGURE_INTERRUPT_STACK_SIZE. The size of the FIQ, ABT and UND mode stack is still defined via linker symbols. These modes are rarely used in applications and the default values provided by the BSP should be sufficient in most cases.
  • Remove the bsp_processor_count linker symbol hack used for the SMP support. This is possible since the interrupt stack area is now allocated by the linker and not allocated from the heap. This makes some configure.ac stuff obsolete. Remove the now superfluous BSP variants altcycv_devkit_smp and realview_pbx_a9_qemu_smp.

bfin:

  • Remove unused magic linker command file allocation of initialization stack. Maybe a previous linker command file copy and paste problem? In the start.S the initialization stack is set to a hard coded value.

lm32, m32c, mips, nios2, riscv, sh, v850:

  • Remove magic linker command file allocation of initialization stack. Reuse interrupt stack for initialization stack.

m68k:

  • Remove magic linker command file allocation of initialization stack. Reuse interrupt stack for initialization stack.

powerpc:

  • Remove magic linker command file allocation of initialization stack. Reuse interrupt stack for initialization stack.
  • Used dedicated memory region (REGION_RTEMSSTACK) for the interrupt stack on BSPs using the shared linkcmds.base (replacement for REGION_RWEXTRA).

sparc:

  • Remove the hard coded initialization stack. Use the interrupt stack for the initialization stack on the boot processor. This saves 16KiB of RAM.

Update #3459.

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