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

Last change on this file since d0dd98c was d0dd98c, checked in by Sebastian Huber <sebastian.huber@…>, on 03/15/23 at 07:55:12

sparc: Add header files to Doxygen group

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