summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/sparc/include
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2017-12-23 18:18:56 +1100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-01-25 08:45:26 +0100
commit2afb22b7e1ebcbe40373ff7e0efae7d207c655a9 (patch)
tree44759efe9374f13200a97e96d91bd9a2b7e5ce2a /cpukit/score/cpu/sparc/include
parentMAINTAINERS: Add myself to Write After Approval. (diff)
downloadrtems-2afb22b7e1ebcbe40373ff7e0efae7d207c655a9.tar.bz2
Remove make preinstall
A speciality of the RTEMS build system was the make preinstall step. It copied header files from arbitrary locations into the build tree. The header files were included via the -Bsome/build/tree/path GCC command line option. This has at least seven problems: * The make preinstall step itself needs time and disk space. * Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error. * There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult. * The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit. * An introduction of a new build system is difficult. * Include paths specified by the -B option are system headers. This may suppress warnings. * The parallel build had sporadic failures on some hosts. This patch removes the make preinstall step. All installed header files are moved to dedicated include directories in the source tree. Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc, etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g. erc32, imx, qoriq, etc. The new cpukit include directories are: * cpukit/include * cpukit/score/cpu/@RTEMS_CPU@/include * cpukit/libnetworking The new BSP include directories are: * bsps/include * bsps/@RTEMS_CPU@/include * bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include There are build tree include directories for generated files. The include directory order favours the most general header file, e.g. it is not possible to override general header files via the include path order. The "bootstrap -p" option was removed. The new "bootstrap -H" option should be used to regenerate the "headers.am" files. Update #3254.
Diffstat (limited to 'cpukit/score/cpu/sparc/include')
-rw-r--r--cpukit/score/cpu/sparc/include/machine/elf_machdep.h92
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/asm.h120
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/cpu.h1202
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/cpuatomic.h14
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h155
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/sparc.h418
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h90
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/types.h53
8 files changed, 2144 insertions, 0 deletions
diff --git a/cpukit/score/cpu/sparc/include/machine/elf_machdep.h b/cpukit/score/cpu/sparc/include/machine/elf_machdep.h
new file mode 100644
index 0000000000..e8f2b630c2
--- /dev/null
+++ b/cpukit/score/cpu/sparc/include/machine/elf_machdep.h
@@ -0,0 +1,92 @@
+/* $NetBSD: elf_machdep.h,v 1.7 2009/05/30 05:56:53 skrll Exp $ */
+
+#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
+#define ELF32_MACHDEP_ID_CASES \
+ case EM_SPARC: \
+ case EM_SPARC32PLUS: \
+ break;
+
+#define ELF64_MACHDEP_ENDIANNESS ELFDATA2MSB
+#define ELF64_MACHDEP_ID_CASES \
+ case EM_SPARC32PLUS: \
+ case EM_SPARCV9: \
+ /* no 64-bit ELF machine types supported */
+
+#define ELF32_MACHDEP_ID EM_SPARC /* XXX right? */
+
+#define ARCH_ELFSIZE 32 /* MD native binary size */
+
+#define R_SPARC_NONE 0
+#define R_SPARC_8 1
+#define R_SPARC_16 2
+#define R_SPARC_32 3
+#define R_SPARC_DISP8 4
+#define R_SPARC_DISP16 5
+#define R_SPARC_DISP32 6
+#define R_SPARC_WDISP30 7
+#define R_SPARC_WDISP22 8
+#define R_SPARC_HI22 9
+#define R_SPARC_22 10
+#define R_SPARC_13 11
+#define R_SPARC_LO10 12
+#define R_SPARC_GOT10 13
+#define R_SPARC_GOT13 14
+#define R_SPARC_GOT22 15
+#define R_SPARC_PC10 16
+#define R_SPARC_PC22 17
+#define R_SPARC_WPLT30 18
+#define R_SPARC_COPY 19
+#define R_SPARC_GLOB_DAT 20
+#define R_SPARC_JMP_SLOT 21
+#define R_SPARC_RELATIVE 22
+#define R_SPARC_UA32 23
+#define R_SPARC_PLT32 24
+#define R_SPARC_HIPLT22 25
+#define R_SPARC_LOPLT10 26
+#define R_SPARC_PCPLT32 27
+#define R_SPARC_PCPLT22 28
+#define R_SPARC_PCPLT10 29
+#define R_SPARC_10 30
+#define R_SPARC_11 31
+#define R_SPARC_64 32
+#define R_SPARC_OLO10 33
+#define R_SPARC_HH22 34
+#define R_SPARC_HM10 35
+#define R_SPARC_LM22 36
+#define R_SPARC_PC_HH22 37
+#define R_SPARC_PC_HM10 38
+#define R_SPARC_PC_LM22 39
+#define R_SPARC_WDISP16 40
+#define R_SPARC_WDISP19 41
+#define R_SPARC_GLOB_JMP 42
+#define R_SPARC_7 43
+#define R_SPARC_5 44
+#define R_SPARC_6 45
+
+/* TLS relocations */
+#define R_SPARC_TLS_GD_HI22 56
+#define R_SPARC_TLS_GD_LO10 57
+#define R_SPARC_TLS_GD_ADD 58
+#define R_SPARC_TLS_GD_CALL 59
+#define R_SPARC_TLS_LDM_HI22 60
+#define R_SPARC_TLS_LDM_LO10 61
+#define R_SPARC_TLS_LDM_ADD 62
+#define R_SPARC_TLS_LDM_CALL 63
+#define R_SPARC_TLS_LDO_HIX22 64
+#define R_SPARC_TLS_LDO_LOX10 65
+#define R_SPARC_TLS_LDO_ADD 66
+#define R_SPARC_TLS_IE_HI22 67
+#define R_SPARC_TLS_IE_LO10 68
+#define R_SPARC_TLS_IE_LD 69
+#define R_SPARC_TLS_IE_LDX 70
+#define R_SPARC_TLS_IE_ADD 71
+#define R_SPARC_TLS_LE_HIX22 72
+#define R_SPARC_TLS_LE_LOX10 73
+#define R_SPARC_TLS_DTPMOD32 74
+#define R_SPARC_TLS_DTPMOD64 75
+#define R_SPARC_TLS_DTPOFF32 76
+#define R_SPARC_TLS_DTPOFF64 77
+#define R_SPARC_TLS_TPOFF32 78
+#define R_SPARC_TLS_TPOFF64 79
+
+#define R_TYPE(name) __CONCAT(R_SPARC_,name)
diff --git a/cpukit/score/cpu/sparc/include/rtems/asm.h b/cpukit/score/cpu/sparc/include/rtems/asm.h
new file mode 100644
index 0000000000..a2b11f63fc
--- /dev/null
+++ b/cpukit/score/cpu/sparc/include/rtems/asm.h
@@ -0,0 +1,120 @@
+/**
+ * @file
+ *
+ * @brief Address the Problems Caused by Incompatible Flavor of
+ * Assemblers and Toolsets
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ *
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ */
+
+/*
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted.
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/cpu.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+/* XXX __USER_LABEL_PREFIX__ and __REGISTER_PREFIX__ do not work on gcc 2.7.0 */
+/* XXX The following ifdef magic fixes the problem but results in a warning */
+/* XXX when compiling assembly code. */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+#include <rtems/concat.h>
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+/*
+ * define macros for all of the registers on this CPU
+ *
+ * EXAMPLE: #define d0 REG (d0)
+ */
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE .text
+#define END_CODE
+#define BEGIN_DATA
+#define END_DATA
+#define BEGIN_BSS
+#define END_BSS
+#define END
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC(sym) .globl SYM (sym)
+#define EXTERN(sym) .globl SYM (sym)
+
+/*
+ * Entry for traps which jump to a programmer-specified trap handler.
+ */
+
+#define TRAP(_vector, _handler) \
+ mov %psr, %l0 ; \
+ sethi %hi(_handler), %l4 ; \
+ jmp %l4+%lo(_handler); \
+ mov _vector, %l3
+
+/*
+ * Used for the reset trap to avoid a supervisor instruction
+ */
+
+#define RTRAP(_vector, _handler) \
+ mov %g0, %l0 ; \
+ sethi %hi(_handler), %l4 ; \
+ jmp %l4+%lo(_handler); \
+ mov _vector, %l3
+
+#endif
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpu.h b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
new file mode 100644
index 0000000000..2b50592e08
--- /dev/null
+++ b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
@@ -0,0 +1,1202 @@
+/**
+ * @file
+ *
+ * @brief SPARC CPU Department Source
+ *
+ * This include file contains information pertaining to the port of
+ * the executive to the SPARC processor.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/types.h>
+#include <rtems/score/sparc.h>
+
+/* conditional compilation parameters */
+
+/*
+ * The SPARC ABI is a bit special with respect to the floating point context.
+ * The complete floating point context is volatile. Thus, from an ABI point
+ * of view nothing needs to be saved and restored during a context switch.
+ * Instead the floating point context must be saved and restored during
+ * interrupt processing. Historically, the deferred floating point switch was
+ * used for SPARC and the complete floating point context is saved and
+ * restored during a context switch to the new floating point unit owner.
+ * This is a bit dangerous since post-switch actions (e.g. signal handlers)
+ * and context switch extensions may silently corrupt the floating point
+ * context.
+ *
+ * The floating point unit is disabled for interrupt handlers. Thus, in case
+ * an interrupt handler uses the floating point unit then this will result in a
+ * trap (INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT).
+ *
+ * In uniprocessor configurations, a lazy floating point context switch is
+ * used. In case an active floating point thread is interrupted (PSR[EF] == 1)
+ * and a thread dispatch is carried out, then this thread is registered as the
+ * floating point owner. When a floating point owner is present during a
+ * context switch, the floating point unit is disabled for the heir thread
+ * (PSR[EF] == 0). The floating point disabled trap checks that the use of the
+ * floating point unit is allowed and saves/restores the floating point context
+ * on demand.
+ *
+ * In SMP configurations, the deferred floating point switch is not supported
+ * in principle. So, use here a synchronous floating point switching.
+ * Synchronous means that the volatile floating point context is saved and
+ * restored around a thread dispatch issued during interrupt processing. Thus
+ * post-switch actions and context switch extensions may safely use the
+ * floating point unit.
+ */
+#if SPARC_HAS_FPU == 1
+ #if defined(RTEMS_SMP)
+ #define SPARC_USE_SYNCHRONOUS_FP_SWITCH
+ #else
+ #define SPARC_USE_LAZY_FP_SWITCH
+ #endif
+#endif
+
+/**
+ * Does the executive manage a dedicated interrupt stack in software?
+ *
+ * If TRUE, then a stack is allocated in _ISR_Handler_initialization.
+ * If FALSE, nothing is done.
+ *
+ * The SPARC does not have a dedicated HW interrupt stack and one has
+ * been implemented in SW.
+ */
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE
+
+/**
+ * Does the CPU follow the simple vectored interrupt model?
+ *
+ * - If TRUE, then RTEMS allocates the vector table it internally manages.
+ * - If FALSE, then the BSP is assumed to allocate and manage the vector
+ * table
+ *
+ * THe SPARC is a simple vectored architecture. Usually there is no
+ * PIC and the CPU directly vectors the interrupts.
+ */
+#define CPU_SIMPLE_VECTORED_INTERRUPTS TRUE
+
+/**
+ * Does this CPU have hardware support for a dedicated interrupt stack?
+ *
+ * - If TRUE, then it must be installed during initialization.
+ * - If FALSE, then no installation is performed.
+ *
+ * The SPARC does not have a dedicated HW interrupt stack.
+ */
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
+
+/**
+ * Do we allocate a dedicated interrupt stack in the Interrupt Manager?
+ *
+ * - If TRUE, then the memory is allocated during initialization.
+ * - If FALSE, then the memory is allocated during initialization.
+ *
+ * The SPARC does not have hardware support for switching to a
+ * dedicated interrupt stack. The port includes support for doing this
+ * in software.
+ *
+ */
+#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
+
+/**
+ * Does the RTEMS invoke the user's ISR with the vector number and
+ * a pointer to the saved interrupt frame (1) or just the vector
+ * number (0)?
+ *
+ * The SPARC port does not pass an Interrupt Stack Frame pointer to
+ * interrupt handlers.
+ */
+#define CPU_ISR_PASSES_FRAME_POINTER FALSE
+
+/**
+ * Does the CPU have hardware floating point?
+ *
+ * - If TRUE, then the FLOATING_POINT task attribute is supported.
+ * - If FALSE, then the FLOATING_POINT task attribute is ignored.
+ *
+ * This is set based upon the multilib settings.
+ */
+#if ( SPARC_HAS_FPU == 1 ) && !defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
+ #define CPU_HARDWARE_FP TRUE
+#else
+ #define CPU_HARDWARE_FP FALSE
+#endif
+
+/**
+ * The SPARC GCC port does not have a software floating point library
+ * that requires RTEMS assistance.
+ */
+#define CPU_SOFTWARE_FP FALSE
+
+/**
+ * Are all tasks FLOATING_POINT tasks implicitly?
+ *
+ * - If TRUE, then the FLOATING_POINT task attribute is assumed.
+ * - If FALSE, then the FLOATING_POINT task attribute is followed.
+ *
+ * The SPARC GCC port does not implicitly use floating point registers.
+ */
+#define CPU_ALL_TASKS_ARE_FP FALSE
+
+/**
+ * Should the IDLE task have a floating point context?
+ *
+ * - If TRUE, then the IDLE task is created as a FLOATING_POINT task
+ * and it has a floating point context which is switched in and out.
+ * - If FALSE, then the IDLE task does not have a floating point context.
+ *
+ * The IDLE task does not have to be floating point on the SPARC.
+ */
+#define CPU_IDLE_TASK_IS_FP FALSE
+
+#define CPU_USE_DEFERRED_FP_SWITCH FALSE
+
+#define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
+
+/**
+ * Does this port provide a CPU dependent IDLE task implementation?
+ *
+ * - If TRUE, then the routine _CPU_Thread_Idle_body
+ * must be provided and is the default IDLE thread body instead of
+ * _CPU_Thread_Idle_body.
+ *
+ * - If FALSE, then use the generic IDLE thread body if the BSP does
+ * not provide one.
+ *
+ * The SPARC architecture does not have a low power or halt instruction.
+ * It is left to the BSP and/or CPU specific code to provide an IDLE
+ * thread body which is aware of low power modes.
+ */
+#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE
+
+/**
+ * Does the stack grow up (toward higher addresses) or down
+ * (toward lower addresses)?
+ *
+ * - If TRUE, then the grows upward.
+ * - If FALSE, then the grows toward smaller addresses.
+ *
+ * The stack grows to lower addresses on the SPARC.
+ */
+#define CPU_STACK_GROWS_UP FALSE
+
+/* LEON3 systems may use a cache line size of 64 */
+#define CPU_CACHE_LINE_BYTES 64
+
+#define CPU_STRUCTURE_ALIGNMENT RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES )
+
+/**
+ * The following defines the number of bits actually used in the
+ * interrupt field of the task mode. How those bits map to the
+ * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
+ *
+ * The SPARC has 16 interrupt levels in the PIL field of the PSR.
+ */
+#define CPU_MODES_INTERRUPT_MASK 0x0000000F
+
+#ifndef ASM
+/**
+ * This structure represents the organization of the minimum stack frame
+ * for the SPARC. More framing information is required in certain situaions
+ * such as when there are a large number of out parameters or when the callee
+ * must save floating point registers.
+ */
+typedef struct {
+ /** This is the offset of the l0 register. */
+ uint32_t l0;
+ /** This is the offset of the l1 register. */
+ uint32_t l1;
+ /** This is the offset of the l2 register. */
+ uint32_t l2;
+ /** This is the offset of the l3 register. */
+ uint32_t l3;
+ /** This is the offset of the l4 register. */
+ uint32_t l4;
+ /** This is the offset of the l5 register. */
+ uint32_t l5;
+ /** This is the offset of the l6 register. */
+ uint32_t l6;
+ /** This is the offset of the l7 register. */
+ uint32_t l7;
+ /** This is the offset of the l0 register. */
+ uint32_t i0;
+ /** This is the offset of the i1 register. */
+ uint32_t i1;
+ /** This is the offset of the i2 register. */
+ uint32_t i2;
+ /** This is the offset of the i3 register. */
+ uint32_t i3;
+ /** This is the offset of the i4 register. */
+ uint32_t i4;
+ /** This is the offset of the i5 register. */
+ uint32_t i5;
+ /** This is the offset of the i6 register. */
+ uint32_t i6_fp;
+ /** This is the offset of the i7 register. */
+ uint32_t i7;
+ /** This is the offset of the register used to return structures. */
+ void *structure_return_address;
+
+ /*
+ * The following are for the callee to save the register arguments in
+ * should this be necessary.
+ */
+ /** This is the offset of the register for saved argument 0. */
+ uint32_t saved_arg0;
+ /** This is the offset of the register for saved argument 1. */
+ uint32_t saved_arg1;
+ /** This is the offset of the register for saved argument 2. */
+ uint32_t saved_arg2;
+ /** This is the offset of the register for saved argument 3. */
+ uint32_t saved_arg3;
+ /** This is the offset of the register for saved argument 4. */
+ uint32_t saved_arg4;
+ /** This is the offset of the register for saved argument 5. */
+ uint32_t saved_arg5;
+ /** This field pads the structure so ldd and std instructions can be used. */
+ uint32_t pad0;
+} SPARC_Minimum_stack_frame;
+
+#endif /* ASM */
+
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_L0_OFFSET 0x00
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_L1_OFFSET 0x04
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_L2_OFFSET 0x08
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_L3_OFFSET 0x0c
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_L4_OFFSET 0x10
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_L5_OFFSET 0x14
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_L6_OFFSET 0x18
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_L7_OFFSET 0x1c
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_I0_OFFSET 0x20
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_I1_OFFSET 0x24
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_I2_OFFSET 0x28
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_I3_OFFSET 0x2c
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_I4_OFFSET 0x30
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_I5_OFFSET 0x34
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_I6_FP_OFFSET 0x38
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_I7_OFFSET 0x3c
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STRUCTURE_RETURN_ADDRESS_OFFSET 0x40
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_SAVED_ARG0_OFFSET 0x44
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_SAVED_ARG1_OFFSET 0x48
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_SAVED_ARG2_OFFSET 0x4c
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_SAVED_ARG3_OFFSET 0x50
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_SAVED_ARG4_OFFSET 0x54
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_SAVED_ARG5_OFFSET 0x58
+/** This macro defines an offset into the stack frame for use in assembly. */
+#define CPU_STACK_FRAME_PAD0_OFFSET 0x5c
+
+#define CPU_MAXIMUM_PROCESSORS 32
+
+/**
+ * @defgroup Contexts SPARC Context Structures
+ *
+ * @ingroup Score
+ *
+ * Generally there are 2 types of context to save.
+ * + Interrupt registers to save
+ * + Task level registers to save
+ *
+ * This means we have the following 3 context items:
+ * + task level context stuff:: Context_Control
+ * + floating point task stuff:: Context_Control_fp
+ * + special interrupt level context :: Context_Control_interrupt
+ *
+ * On the SPARC, we are relatively conservative in that we save most
+ * of the CPU state in the context area. The ET (enable trap) bit and
+ * the CWP (current window pointer) fields of the PSR are considered
+ * system wide resources and are not maintained on a per-thread basis.
+ */
+/**@{**/
+
+#ifndef ASM
+typedef struct Context_Control_fp Context_Control_fp;
+
+/**
+ * @brief SPARC basic context.
+ *
+ * This structure defines the non-volatile integer and processor state context
+ * for the SPARC architecture according to "SYSTEM V APPLICATION BINARY
+ * INTERFACE - SPARC Processor Supplement", Third Edition.
+ *
+ * The registers g2 through g4 are reserved for applications. GCC uses them as
+ * volatile registers by default. So they are treated like volatile registers
+ * in RTEMS as well.
+ *
+ * The register g6 contains the per-CPU control of the current processor. It
+ * is an invariant of the processor context. This register must not be saved
+ * and restored during context switches or interrupt services.
+ */
+typedef struct {
+ /** This will contain the contents of the g5 register. */
+ uint32_t g5;
+ /** This will contain the contents of the g7 register. */
+ uint32_t g7;
+
+ /**
+ * This will contain the contents of the l0 and l1 registers.
+ *
+ * Using a double l0_and_l1 will put everything in this structure on a double
+ * word boundary which allows us to use double word loads and stores safely
+ * in the context switch.
+ */
+ double l0_and_l1;
+ /** This will contain the contents of the l2 register. */
+ uint32_t l2;
+ /** This will contain the contents of the l3 register. */
+ uint32_t l3;
+ /** This will contain the contents of the l4 register. */
+ uint32_t l4;
+ /** This will contain the contents of the l5 registeer.*/
+ uint32_t l5;
+ /** This will contain the contents of the l6 register. */
+ uint32_t l6;
+ /** This will contain the contents of the l7 register. */
+ uint32_t l7;
+
+ /** This will contain the contents of the i0 register. */
+ uint32_t i0;
+ /** This will contain the contents of the i1 register. */
+ uint32_t i1;
+ /** This will contain the contents of the i2 register. */
+ uint32_t i2;
+ /** This will contain the contents of the i3 register. */
+ uint32_t i3;
+ /** This will contain the contents of the i4 register. */
+ uint32_t i4;
+ /** This will contain the contents of the i5 register. */
+ uint32_t i5;
+ /** This will contain the contents of the i6 (e.g. frame pointer) register. */
+ uint32_t i6_fp;
+ /** This will contain the contents of the i7 register. */
+ uint32_t i7;
+
+ /** This will contain the contents of the o6 (e.g. frame pointer) register. */
+ uint32_t o6_sp;
+ /**
+ * This will contain the contents of the o7 (e.g. address of CALL
+ * instruction) register.
+ */
+ uint32_t o7;
+
+ /** This will contain the contents of the processor status register. */
+ uint32_t psr;
+ /**
+ * This field is used to prevent heavy nesting of calls to _Thread_Dispatch
+ * on an interrupted task's stack. This is problematic on the slower
+ * SPARC CPU models at high interrupt rates.
+ */
+ uint32_t isr_dispatch_disable;
+
+#if defined(SPARC_USE_LAZY_FP_SWITCH)
+ Context_Control_fp *fp_context;
+#endif
+
+#if defined(RTEMS_SMP)
+ volatile uint32_t is_executing;
+#endif
+} Context_Control;
+
+/**
+ * This macro provides a CPU independent way for RTEMS to access the
+ * stack pointer in a context structure. The actual name and offset is
+ * CPU architecture dependent.
+ */
+#define _CPU_Context_Get_SP( _context ) \
+ (_context)->o6_sp
+
+#ifdef RTEMS_SMP
+ static inline bool _CPU_Context_Get_is_executing(
+ const Context_Control *context
+ )
+ {
+ return context->is_executing;
+ }
+
+ static inline void _CPU_Context_Set_is_executing(
+ Context_Control *context,
+ bool is_executing
+ )
+ {
+ context->is_executing = is_executing;
+ }
+#endif
+
+#endif /* ASM */
+
+/*
+ * Offsets of fields with Context_Control for assembly routines.
+ */
+
+/** This macro defines an offset into the context for use in assembly. */
+#define G5_OFFSET 0x00
+/** This macro defines an offset into the context for use in assembly. */
+#define G7_OFFSET 0x04
+
+/** This macro defines an offset into the context for use in assembly. */
+#define L0_OFFSET 0x08
+/** This macro defines an offset into the context for use in assembly. */
+#define L1_OFFSET 0x0C
+/** This macro defines an offset into the context for use in assembly. */
+#define L2_OFFSET 0x10
+/** This macro defines an offset into the context for use in assembly. */
+#define L3_OFFSET 0x14
+/** This macro defines an offset into the context for use in assembly. */
+#define L4_OFFSET 0x18
+/** This macro defines an offset into the context for use in assembly. */
+#define L5_OFFSET 0x1C
+/** This macro defines an offset into the context for use in assembly. */
+#define L6_OFFSET 0x20
+/** This macro defines an offset into the context for use in assembly. */
+#define L7_OFFSET 0x24
+
+/** This macro defines an offset into the context for use in assembly. */
+#define I0_OFFSET 0x28
+/** This macro defines an offset into the context for use in assembly. */
+#define I1_OFFSET 0x2C
+/** This macro defines an offset into the context for use in assembly. */
+#define I2_OFFSET 0x30
+/** This macro defines an offset into the context for use in assembly. */
+#define I3_OFFSET 0x34
+/** This macro defines an offset into the context for use in assembly. */
+#define I4_OFFSET 0x38
+/** This macro defines an offset into the context for use in assembly. */
+#define I5_OFFSET 0x3C
+/** This macro defines an offset into the context for use in assembly. */
+#define I6_FP_OFFSET 0x40
+/** This macro defines an offset into the context for use in assembly. */
+#define I7_OFFSET 0x44
+
+/** This macro defines an offset into the context for use in assembly. */
+#define O6_SP_OFFSET 0x48
+/** This macro defines an offset into the context for use in assembly. */
+#define O7_OFFSET 0x4C
+
+/** This macro defines an offset into the context for use in assembly. */
+#define PSR_OFFSET 0x50
+/** This macro defines an offset into the context for use in assembly. */
+#define ISR_DISPATCH_DISABLE_STACK_OFFSET 0x54
+
+#if defined(RTEMS_SMP)
+ #define SPARC_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 0x58
+#endif
+
+#ifndef ASM
+/**
+ * @brief SPARC basic context.
+ *
+ * This structure defines floating point context area.
+ */
+struct Context_Control_fp {
+ /** This will contain the contents of the f0 and f1 register. */
+ double f0_f1;
+ /** This will contain the contents of the f2 and f3 register. */
+ double f2_f3;
+ /** This will contain the contents of the f4 and f5 register. */
+ double f4_f5;
+ /** This will contain the contents of the f6 and f7 register. */
+ double f6_f7;
+ /** This will contain the contents of the f8 and f9 register. */
+ double f8_f9;
+ /** This will contain the contents of the f10 and f11 register. */
+ double f10_f11;
+ /** This will contain the contents of the f12 and f13 register. */
+ double f12_f13;
+ /** This will contain the contents of the f14 and f15 register. */
+ double f14_f15;
+ /** This will contain the contents of the f16 and f17 register. */
+ double f16_f17;
+ /** This will contain the contents of the f18 and f19 register. */
+ double f18_f19;
+ /** This will contain the contents of the f20 and f21 register. */
+ double f20_f21;
+ /** This will contain the contents of the f22 and f23 register. */
+ double f22_f23;
+ /** This will contain the contents of the f24 and f25 register. */
+ double f24_f25;
+ /** This will contain the contents of the f26 and f27 register. */
+ double f26_f27;
+ /** This will contain the contents of the f28 and f29 register. */
+ double f28_f29;
+ /** This will contain the contents of the f30 and f31 register. */
+ double f30_f31;
+ /** This will contain the contents of the floating point status register. */
+ uint32_t fsr;
+};
+
+#endif /* ASM */
+
+/*
+ * Offsets of fields with Context_Control_fp for assembly routines.
+ */
+
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define FO_F1_OFFSET 0x00
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F2_F3_OFFSET 0x08
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F4_F5_OFFSET 0x10
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F6_F7_OFFSET 0x18
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F8_F9_OFFSET 0x20
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F1O_F11_OFFSET 0x28
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F12_F13_OFFSET 0x30
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F14_F15_OFFSET 0x38
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F16_F17_OFFSET 0x40
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F18_F19_OFFSET 0x48
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F2O_F21_OFFSET 0x50
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F22_F23_OFFSET 0x58
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F24_F25_OFFSET 0x60
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F26_F27_OFFSET 0x68
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F28_F29_OFFSET 0x70
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define F3O_F31_OFFSET 0x78
+/** This macro defines an offset into the FPU context for use in assembly. */
+#define FSR_OFFSET 0x80
+
+/** This defines the size of the FPU context area for use in assembly. */
+#define CONTEXT_CONTROL_FP_SIZE 0x84
+
+#ifndef ASM
+
+/** @} */
+
+/**
+ * @brief Interrupt stack frame (ISF).
+ *
+ * Context saved on stack for an interrupt.
+ *
+ * NOTE: The PSR, PC, and NPC are only saved in this structure for the
+ * benefit of the user's handler.
+ */
+typedef struct {
+ /** On an interrupt, we must save the minimum stack frame. */
+ SPARC_Minimum_stack_frame Stack_frame;
+ /** This is the offset of the PSR on an ISF. */
+ uint32_t psr;
+ /** This is the offset of the XXX on an ISF. */
+ uint32_t pc;
+ /** This is the offset of the XXX on an ISF. */
+ uint32_t npc;
+ /** This is the offset of the g1 register on an ISF. */
+ uint32_t g1;
+ /** This is the offset of the g2 register on an ISF. */
+ uint32_t g2;
+ /** This is the offset of the g3 register on an ISF. */
+ uint32_t g3;
+ /** This is the offset of the g4 register on an ISF. */
+ uint32_t g4;
+ /** This is the offset of the g5 register on an ISF. */
+ uint32_t g5;
+ /** This is the offset is reserved for alignment on an ISF. */
+ uint32_t reserved_for_alignment;
+ /** This is the offset of the g7 register on an ISF. */
+ uint32_t g7;
+ /** This is the offset of the i0 register on an ISF. */
+ uint32_t i0;
+ /** This is the offset of the i1 register on an ISF. */
+ uint32_t i1;
+ /** This is the offset of the i2 register on an ISF. */
+ uint32_t i2;
+ /** This is the offset of the i3 register on an ISF. */
+ uint32_t i3;
+ /** This is the offset of the i4 register on an ISF. */
+ uint32_t i4;
+ /** This is the offset of the i5 register on an ISF. */
+ uint32_t i5;
+ /** This is the offset of the i6 register on an ISF. */
+ uint32_t i6_fp;
+ /** This is the offset of the i7 register on an ISF. */
+ uint32_t i7;
+ /** This is the offset of the y register on an ISF. */
+ uint32_t y;
+ /** This is the offset of the tpc register on an ISF. */
+ uint32_t tpc;
+} CPU_Interrupt_frame;
+
+#endif /* ASM */
+
+#ifndef ASM
+/**
+ * The following type defines an entry in the SPARC's trap table.
+ *
+ * NOTE: The instructions chosen are RTEMS dependent although one is
+ * obligated to use two of the four instructions to perform a
+ * long jump. The other instructions load one register with the
+ * trap type (a.k.a. vector) and another with the psr.
+ */
+typedef struct {
+ /** This will contain a "mov %psr, %l0" instruction. */
+ uint32_t mov_psr_l0;
+ /** This will contain a "sethi %hi(_handler), %l4" instruction. */
+ uint32_t sethi_of_handler_to_l4;
+ /** This will contain a "jmp %l4 + %lo(_handler)" instruction. */
+ uint32_t jmp_to_low_of_handler_plus_l4;
+ /** This will contain a " mov _vector, %l3" instruction. */
+ uint32_t mov_vector_l3;
+} CPU_Trap_table_entry;
+
+/**
+ * This is the set of opcodes for the instructions loaded into a trap
+ * table entry. The routine which installs a handler is responsible
+ * for filling in the fields for the _handler address and the _vector
+ * trap type.
+ *
+ * The constants following this structure are masks for the fields which
+ * must be filled in when the handler is installed.
+ */
+extern const CPU_Trap_table_entry _CPU_Trap_slot_template;
+
+/**
+ * The size of the floating point context area.
+ */
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+#endif
+
+/**
+ * Amount of extra stack (above minimum stack size) required by
+ * MPCI receive server thread. Remember that in a multiprocessor
+ * system this thread must exist and be able to process all directives.
+ */
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 1024
+
+/**
+ * This defines the number of entries in the ISR_Vector_table managed
+ * by the executive.
+ *
+ * On the SPARC, there are really only 256 vectors. However, the executive
+ * has no easy, fast, reliable way to determine which traps are synchronous
+ * and which are asynchronous. By default, synchronous traps return to the
+ * instruction which caused the interrupt. So if you install a software
+ * trap handler as an executive interrupt handler (which is desirable since
+ * RTEMS takes care of window and register issues), then the executive needs
+ * to know that the return address is to the trap rather than the instruction
+ * following the trap.
+ *
+ * So vectors 0 through 255 are treated as regular asynchronous traps which
+ * provide the "correct" return address. Vectors 256 through 512 are assumed
+ * by the executive to be synchronous and to require that the return address
+ * be fudged.
+ *
+ * If you use this mechanism to install a trap handler which must reexecute
+ * the instruction which caused the trap, then it should be installed as
+ * an asynchronous trap. This will avoid the executive changing the return
+ * address.
+ */
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
+
+/**
+ * The SPARC has 256 vectors but the port treats 256-512 as synchronous
+ * traps.
+ */
+#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER 511
+
+/**
+ * This is the bit step in a vector number to indicate it is being installed
+ * as a synchronous trap.
+ */
+#define SPARC_SYNCHRONOUS_TRAP_BIT_MASK 0x100
+
+/**
+ * This macro indicates that @a _trap as an asynchronous trap.
+ */
+#define SPARC_ASYNCHRONOUS_TRAP( _trap ) (_trap)
+
+/**
+ * This macro indicates that @a _trap as a synchronous trap.
+ */
+#define SPARC_SYNCHRONOUS_TRAP( _trap ) ((_trap) + 256 )
+
+/**
+ * This macro returns the real hardware vector number associated with @a _trap.
+ */
+#define SPARC_REAL_TRAP_NUMBER( _trap ) ((_trap) % 256)
+
+/**
+ * This is defined if the port has a special way to report the ISR nesting
+ * level. Most ports maintain the variable _ISR_Nest_level.
+ */
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+/**
+ * Should be large enough to run all tests. This ensures
+ * that a "reasonable" small application should not have any problems.
+ *
+ * This appears to be a fairly generous number for the SPARC since
+ * represents a call depth of about 20 routines based on the minimum
+ * stack frame.
+ */
+#define CPU_STACK_MINIMUM_SIZE (1024*4)
+
+/**
+ * What is the size of a pointer on this architecture?
+ */
+#define CPU_SIZEOF_POINTER 4
+
+/**
+ * CPU's worst alignment requirement for data types on a byte boundary. This
+ * alignment does not take into account the requirements for the stack.
+ *
+ * On the SPARC, this is required for double word loads and stores.
+ */
+#define CPU_ALIGNMENT 8
+
+/**
+ * This number corresponds to the byte alignment requirement for the
+ * heap handler. This alignment requirement may be stricter than that
+ * for the data types alignment specified by CPU_ALIGNMENT. It is
+ * common for the heap to follow the same alignment requirement as
+ * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
+ * then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+
+/**
+ * This number corresponds to the byte alignment requirement for memory
+ * buffers allocated by the partition manager. This alignment requirement
+ * may be stricter than that for the data types alignment specified by
+ * CPU_ALIGNMENT. It is common for the partition to follow the same
+ * alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict
+ * enough for the partition, then this should be set to CPU_ALIGNMENT.
+ *
+ * NOTE: This does not have to be a power of 2. It does have to
+ * be greater or equal to than CPU_ALIGNMENT.
+ */
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/**
+ * Stack frames must be doubleword aligned according to the System V ABI for
+ * SPARC.
+ */
+#define CPU_STACK_ALIGNMENT CPU_ALIGNMENT
+
+#ifndef ASM
+
+/*
+ * ISR handler macros
+ */
+
+/**
+ * Support routine to initialize the RTEMS vector table after it is allocated.
+ */
+#define _CPU_Initialize_vectors()
+
+/**
+ * Disable all interrupts for a critical section. The previous
+ * level is returned in _level.
+ */
+#define _CPU_ISR_Disable( _level ) \
+ (_level) = sparc_disable_interrupts()
+
+/**
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of a critical section. The parameter
+ * _level is not modified.
+ */
+#define _CPU_ISR_Enable( _level ) \
+ sparc_enable_interrupts( _level )
+
+/**
+ * This temporarily restores the interrupt to _level before immediately
+ * disabling them again. This is used to divide long critical
+ * sections into two or more parts. The parameter _level is not
+ * modified.
+ */
+#define _CPU_ISR_Flash( _level ) \
+ sparc_flash_interrupts( _level )
+
+#define _CPU_ISR_Is_enabled( _isr_cookie ) \
+ sparc_interrupt_is_enabled( _isr_cookie )
+
+RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level )
+{
+ return ( level & SPARC_PSR_PIL_MASK ) == 0;
+}
+
+/**
+ * Map interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a straight fashion are undefined.
+ */
+#define _CPU_ISR_Set_level( _newlevel ) \
+ sparc_enable_interrupts( _newlevel << 8)
+
+/**
+ * @brief Obtain the current interrupt disable level.
+ *
+ * This method is invoked to return the current interrupt disable level.
+ *
+ * @return This method returns the current interrupt disable level.
+ */
+uint32_t _CPU_ISR_Get_level( void );
+
+/* end of ISR handler macros */
+
+/* Context handler macros */
+
+/**
+ * Initialize the context to a state suitable for starting a
+ * task after a context restore operation. Generally, this
+ * involves:
+ *
+ * - setting a starting address
+ * - preparing the stack
+ * - preparing the stack and frame pointers
+ * - setting the proper interrupt level in the context
+ * - initializing the floating point context
+ *
+ * @param[in] the_context points to the context area
+ * @param[in] stack_base is the low address of the allocated stack area
+ * @param[in] size is the size of the stack area in bytes
+ * @param[in] new_level is the interrupt level for the task
+ * @param[in] entry_point is the task's entry point
+ * @param[in] is_fp is set to TRUE if the task is a floating point task
+ * @param[in] tls_area is the thread-local storage (TLS) area
+ *
+ * NOTE: Implemented as a subroutine for the SPARC port.
+ */
+void _CPU_Context_Initialize(
+ Context_Control *the_context,
+ uint32_t *stack_base,
+ uint32_t size,
+ uint32_t new_level,
+ void *entry_point,
+ bool is_fp,
+ void *tls_area
+);
+
+/**
+ * This macro is invoked from _Thread_Handler to do whatever CPU
+ * specific magic is required that must be done in the context of
+ * the thread when it starts.
+ *
+ * On the SPARC, this is setting the frame pointer so GDB is happy.
+ * Make GDB stop unwinding at _Thread_Handler, previous register window
+ * Frame pointer is 0 and calling address must be a function with starting
+ * with a SAVE instruction. If return address is leaf-function (no SAVE)
+ * GDB will not look at prev reg window fp.
+ *
+ * _Thread_Handler is known to start with SAVE.
+ */
+#define _CPU_Context_Initialization_at_thread_begin() \
+ do { \
+ __asm__ volatile ("set _Thread_Handler,%%i7\n"::); \
+ } while (0)
+
+/**
+ * This routine is responsible for somehow restarting the currently
+ * executing task.
+ *
+ * On the SPARC, this is is relatively painless but requires a small
+ * amount of wrapper code before using the regular restore code in
+ * of the context switch.
+ */
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+/**
+ * @brief Nothing to do due to the synchronous or lazy floating point switch.
+ */
+#define _CPU_Context_Initialize_fp( _destination ) \
+ do { } while ( 0 )
+
+/**
+ * @brief Nothing to do due to the synchronous or lazy floating point switch.
+ */
+#define _CPU_Context_save_fp( _fp_context_ptr ) \
+ do { } while ( 0 )
+
+/**
+ * @brief Nothing to do due to the synchronous or lazy floating point switch.
+ */
+#define _CPU_Context_restore_fp( _fp_context_ptr ) \
+ do { } while ( 0 )
+/* end of Context handler macros */
+
+/* Fatal Error manager macros */
+
+/**
+ * This routine copies _error into a known place -- typically a stack
+ * location or a register, optionally disables interrupts, and
+ * halts/stops the CPU.
+ */
+extern void _CPU_Fatal_halt(uint32_t source, uint32_t error)
+ RTEMS_NO_RETURN;
+
+/* end of Fatal Error manager macros */
+
+/* Bitfield handler macros */
+
+#if ( SPARC_HAS_BITSCAN == 0 )
+ /**
+ * The SPARC port uses the generic C algorithm for bitfield scan if the
+ * CPU model does not have a scan instruction.
+ */
+ #define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+#else
+ #error "scan instruction not currently supported by RTEMS!!"
+#endif
+
+/* end of Bitfield handler macros */
+
+/* functions */
+
+/**
+ * @brief SPARC specific initialization.
+ *
+ * This routine performs CPU dependent initialization.
+ */
+void _CPU_Initialize(void);
+
+/**
+ * @brief SPARC specific raw ISR installer.
+ *
+ * This routine installs @a new_handler to be directly called from the trap
+ * table.
+ *
+ * @param[in] vector is the vector number
+ * @param[in] new_handler is the new ISR handler
+ * @param[in] old_handler will contain the old ISR handler
+ */
+void _CPU_ISR_install_raw_handler(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/**
+ * @brief SPARC specific RTEMS ISR installer.
+ *
+ * This routine installs an interrupt vector.
+ *
+ * @param[in] vector is the vector number
+ * @param[in] new_handler is the new ISR handler
+ * @param[in] old_handler will contain the old ISR handler
+ */
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/**
+ * @brief SPARC specific context switch.
+ *
+ * This routine switches from the run context to the heir context.
+ *
+ * @param[in] run is the currently executing thread
+ * @param[in] heir will become the currently executing thread
+ */
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/**
+ * @brief SPARC specific context restore.
+ *
+ * This routine is generally used only to restart self in an
+ * efficient manner.
+ *
+ * @param[in] new_context is the context to restore
+ */
+void _CPU_Context_restore(
+ Context_Control *new_context
+) RTEMS_NO_RETURN;
+
+#if defined(RTEMS_SMP)
+ uint32_t _CPU_SMP_Initialize( void );
+
+ bool _CPU_SMP_Start_processor( uint32_t cpu_index );
+
+ void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
+
+ void _CPU_SMP_Prepare_start_multitasking( void );
+
+ #if defined(__leon__) && !defined(RTEMS_PARAVIRT)
+ static inline uint32_t _CPU_SMP_Get_current_processor( void )
+ {
+ return _LEON3_Get_current_processor();
+ }
+ #else
+ uint32_t _CPU_SMP_Get_current_processor( void );
+ #endif
+
+ void _CPU_SMP_Send_interrupt( uint32_t target_processor_index );
+
+ static inline void _CPU_SMP_Processor_event_broadcast( void )
+ {
+ __asm__ volatile ( "" : : : "memory" );
+ }
+
+ static inline void _CPU_SMP_Processor_event_receive( void )
+ {
+ __asm__ volatile ( "" : : : "memory" );
+ }
+#endif
+
+#if defined(SPARC_USE_LAZY_FP_SWITCH)
+#define _CPU_Context_Destroy( _the_thread, _the_context ) \
+ do { \
+ Per_CPU_Control *cpu_self = _Per_CPU_Get(); \
+ Thread_Control *_fp_owner = cpu_self->cpu_per_cpu.fp_owner; \
+ if ( _fp_owner == _the_thread ) { \
+ cpu_self->cpu_per_cpu.fp_owner = NULL; \
+ } \
+ } while ( 0 )
+#endif
+
+void _CPU_Context_volatile_clobber( uintptr_t pattern );
+
+void _CPU_Context_validate( uintptr_t pattern );
+
+typedef struct {
+ uint32_t trap;
+ CPU_Interrupt_frame *isf;
+} CPU_Exception_frame;
+
+void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
+
+/**
+ * @brief SPARC specific method to endian swap an uint32_t.
+ *
+ * The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ *
+ * @param[in] value is the value to endian swap
+ *
+ * This version will work on any processor, but if you come across a better
+ * way for the SPARC PLEASE use it. The most common way to swap a 32-bit
+ * entity as shown below is not any more efficient on the SPARC.
+ *
+ * - swap least significant two bytes with 16-bit rotate
+ * - swap upper and lower 16-bits
+ * - swap most significant two bytes with 16-bit rotate
+ *
+ * It is not obvious how the SPARC can do significantly better than the
+ * generic code. gcc 2.7.0 only generates about 12 instructions for the
+ * following code at optimization level four (i.e. -O4).
+ */
+static inline uint32_t CPU_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t byte1, byte2, byte3, byte4, swapped;
+
+ byte4 = (value >> 24) & 0xff;
+ byte3 = (value >> 16) & 0xff;
+ byte2 = (value >> 8) & 0xff;
+ byte1 = value & 0xff;
+
+ swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
+ return( swapped );
+}
+
+/**
+ * @brief SPARC specific method to endian swap an uint16_t.
+ *
+ * The following routine swaps the endian format of a uint16_t.
+ *
+ * @param[in] value is the value to endian swap
+ */
+#define CPU_swap_u16( value ) \
+ (((value&0xff) << 8) | ((value >> 8)&0xff))
+
+typedef uint32_t CPU_Counter_ticks;
+
+typedef CPU_Counter_ticks ( *SPARC_Counter_read )( void );
+
+typedef CPU_Counter_ticks ( *SPARC_Counter_difference )(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+);
+
+/*
+ * The SPARC processors supported by RTEMS have no built-in CPU counter
+ * support. We have to use some hardware counter module for this purpose, for
+ * example the GPTIMER instance used by the clock driver. The BSP must provide
+ * an implementation of the CPU counter read and difference functions. This
+ * allows the use of dynamic hardware enumeration.
+ */
+typedef struct {
+ SPARC_Counter_read counter_read;
+ SPARC_Counter_difference counter_difference;
+ volatile const CPU_Counter_ticks *counter_address;
+} SPARC_Counter;
+
+extern const SPARC_Counter _SPARC_Counter;
+
+static inline CPU_Counter_ticks _CPU_Counter_read( void )
+{
+ return ( *_SPARC_Counter.counter_read )();
+}
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return ( *_SPARC_Counter.counter_difference )( second, first );
+}
+
+#endif /* ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/sparc/include/rtems/score/cpuatomic.h
new file mode 100644
index 0000000000..598ee76b20
--- /dev/null
+++ b/cpukit/score/cpu/sparc/include/rtems/score/cpuatomic.h
@@ -0,0 +1,14 @@
+/*
+ * COPYRIGHT (c) 2012-2013 Deng Hengyi.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
+#define _RTEMS_SCORE_ATOMIC_CPU_H
+
+#include <rtems/score/cpustdatomic.h>
+
+#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h
new file mode 100644
index 0000000000..4f2311e755
--- /dev/null
+++ b/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h
@@ -0,0 +1,155 @@
+/**
+ * @file
+ *
+ * @brief CPU Port Implementation API
+ */
+
+/*
+ * Copyright (c) 1989, 2007 On-Line Applications Research Corporation (OAR)
+ * Copyright (c) 2013, 2016 embedded brains GmbH
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_CPUIMPL_H
+#define _RTEMS_SCORE_CPUIMPL_H
+
+#include <rtems/score/cpu.h>
+
+/** This defines the size of the minimum stack frame. */
+#define SPARC_MINIMUM_STACK_FRAME_SIZE 0x60
+
+/*
+ * Offsets of fields with CPU_Interrupt_frame for assembly routines.
+ */
+
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_PSR_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x00
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_PC_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x04
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_NPC_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x08
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_G1_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x0c
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_G2_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x10
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_G3_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x14
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_G4_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x18
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_G5_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x1c
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_G7_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x24
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_I0_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x28
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_I1_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x2c
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_I2_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x30
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_I3_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x34
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_I4_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x38
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_I5_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x3c
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_I6_FP_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x40
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_I7_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x44
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_Y_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x48
+/** This macro defines an offset into the ISF for use in assembly. */
+#define ISF_TPC_OFFSET SPARC_MINIMUM_STACK_FRAME_SIZE + 0x4c
+
+/** This defines the size of the ISF area for use in assembly. */
+#define CPU_INTERRUPT_FRAME_SIZE SPARC_MINIMUM_STACK_FRAME_SIZE + 0x50
+
+#define SPARC_FP_CONTEXT_OFFSET_F0_F1 0
+#define SPARC_FP_CONTEXT_OFFSET_F2_F3 8
+#define SPARC_FP_CONTEXT_OFFSET_F4_F5 16
+#define SPARC_FP_CONTEXT_OFFSET_F6_F7 24
+#define SPARC_FP_CONTEXT_OFFSET_F8_F9 32
+#define SPARC_FP_CONTEXT_OFFSET_F10_F11 40
+#define SPARC_FP_CONTEXT_OFFSET_F12_F13 48
+#define SPARC_FP_CONTEXT_OFFSET_F14_F15 56
+#define SPARC_FP_CONTEXT_OFFSET_F16_F17 64
+#define SPARC_FP_CONTEXT_OFFSET_F18_F19 72
+#define SPARC_FP_CONTEXT_OFFSET_F20_F21 80
+#define SPARC_FP_CONTEXT_OFFSET_F22_F23 88
+#define SPARC_FP_CONTEXT_OFFSET_F24_F25 96
+#define SPARC_FP_CONTEXT_OFFSET_F26_F27 104
+#define SPARC_FP_CONTEXT_OFFSET_F28_F29 112
+#define SPARC_FP_CONTEXT_OFFSET_F30_F31 120
+#define SPARC_FP_CONTEXT_OFFSET_FSR 128
+
+#if ( SPARC_HAS_FPU == 1 )
+ #define CPU_PER_CPU_CONTROL_SIZE 8
+#else
+ #define CPU_PER_CPU_CONTROL_SIZE 0
+#endif
+
+#if ( SPARC_HAS_FPU == 1 )
+ /**
+ * @brief Offset of the CPU_Per_CPU_control::fsr field relative to the
+ * Per_CPU_Control begin.
+ */
+ #define SPARC_PER_CPU_FSR_OFFSET 0
+
+ #if defined(SPARC_USE_LAZY_FP_SWITCH)
+ /**
+ * @brief Offset of the CPU_Per_CPU_control::fp_owner field relative to the
+ * Per_CPU_Control begin.
+ */
+ #define SPARC_PER_CPU_FP_OWNER_OFFSET 4
+ #endif
+#endif
+
+#ifndef ASM
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+#if ( SPARC_HAS_FPU == 1 )
+ /**
+ * @brief Memory location to store the FSR register during interrupt
+ * processing.
+ *
+ * This is a write-only field. The FSR is written to force a completion of
+ * floating point operations in progress.
+ */
+ uint32_t fsr;
+
+#if defined(SPARC_USE_LAZY_FP_SWITCH)
+ /**
+ * @brief The current floating point owner.
+ */
+ struct _Thread_Control *fp_owner;
+#else
+ /* See Per_CPU_Control::Interrupt_frame */
+ uint32_t reserved_for_alignment_of_interrupt_frame;
+#endif
+#endif
+} CPU_Per_CPU_control;
+
+/**
+ * @brief The pointer to the current per-CPU control is available via register
+ * g6.
+ */
+register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__( "g6" );
+
+#define _CPU_Get_current_per_CPU_control() _SPARC_Per_CPU_current
+
+#define _CPU_Get_thread_executing() ( _SPARC_Per_CPU_current->executing )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ASM */
+
+#endif /* _RTEMS_SCORE_CPUIMPL_H */
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/sparc.h b/cpukit/score/cpu/sparc/include/rtems/score/sparc.h
new file mode 100644
index 0000000000..747d013559
--- /dev/null
+++ b/cpukit/score/cpu/sparc/include/rtems/score/sparc.h
@@ -0,0 +1,418 @@
+/**
+ * @file
+ *
+ * @brief Information Required to Build RTEMS for a Particular Member
+ * of the SPARC Family
+ *
+ * This file contains the information required to build
+ * RTEMS for a particular member of the SPARC family. It does
+ * this by setting variables to indicate which implementation
+ * dependent features are present in a particular member
+ * of the family.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_SPARC_H
+#define _RTEMS_SCORE_SPARC_H
+
+#include <rtems/score/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *
+ * Currently recognized feature flags:
+ *
+ * + SPARC_HAS_FPU
+ * 0 - no HW FPU
+ * 1 - has HW FPU (assumed to be compatible w/90C602)
+ *
+ * + SPARC_HAS_BITSCAN
+ * 0 - does not have scan instructions
+ * 1 - has scan instruction (not currently implemented)
+ *
+ * + SPARC_NUMBER_OF_REGISTER_WINDOWS
+ * 8 is the most common number supported by SPARC implementations.
+ * SPARC_PSR_CWP_MASK is derived from this value.
+ */
+
+/**
+ * Some higher end SPARCs have a bitscan instructions. It would
+ * be nice to take advantage of them. Right now, there is no
+ * port to a CPU model with this feature and no (untested) code
+ * that is based on this feature flag.
+ */
+#define SPARC_HAS_BITSCAN 0
+
+/**
+ * This should be OK until a port to a higher end SPARC processor
+ * is made that has more than 8 register windows. If this cannot
+ * be determined based on multilib settings (v7/v8/v9), then the
+ * cpu_asm.S code that depends on this will have to move to libcpu.
+ */
+#define SPARC_NUMBER_OF_REGISTER_WINDOWS 8
+
+/**
+ * See GRLIB-TN-0009: "LEON3FT Stale Cache Entry After Store with
+ * Data Tag Parity Error"
+ */
+#if defined(__FIX_LEON3FT_B2BST)
+ #define SPARC_LEON3FT_B2BST_NOP nop
+#else
+ #define SPARC_LEON3FT_B2BST_NOP
+#endif
+
+/**
+ * This macro indicates whether this multilib variation has hardware
+ * floating point or not. We use the gcc cpp predefine _SOFT_FLOAT
+ * to determine that.
+ */
+#if defined(_SOFT_FLOAT)
+ #define SPARC_HAS_FPU 0
+#else
+ #define SPARC_HAS_FPU 1
+#endif
+
+/**
+ * This macro contains a string describing the multilib variant being
+ * build.
+ */
+#if SPARC_HAS_FPU
+ #define CPU_MODEL_NAME "w/FPU"
+#else
+ #define CPU_MODEL_NAME "w/soft-float"
+#endif
+
+/**
+ * Define the name of the CPU family.
+ */
+#define CPU_NAME "SPARC"
+
+/*
+ * Miscellaneous constants
+ */
+
+/**
+ * PSR masks and starting bit positions
+ *
+ * NOTE: Reserved bits are ignored.
+ */
+#if (SPARC_NUMBER_OF_REGISTER_WINDOWS == 8)
+ #define SPARC_PSR_CWP_MASK 0x07 /* bits 0 - 4 */
+#elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 16)
+ #define SPARC_PSR_CWP_MASK 0x0F /* bits 0 - 4 */
+#elif (SPARC_NUMBER_OF_REGISTER_WINDOWS == 32)
+ #define SPARC_PSR_CWP_MASK 0x1F /* bits 0 - 4 */
+#else
+ #error "Unsupported number of register windows for this cpu"
+#endif
+
+/** This constant is a mask for the ET bits in the PSR. */
+#define SPARC_PSR_ET_MASK 0x00000020 /* bit 5 */
+/** This constant is a mask for the PS bits in the PSR. */
+#define SPARC_PSR_PS_MASK 0x00000040 /* bit 6 */
+/** This constant is a mask for the S bits in the PSR. */
+#define SPARC_PSR_S_MASK 0x00000080 /* bit 7 */
+/** This constant is a mask for the PIL bits in the PSR. */
+#define SPARC_PSR_PIL_MASK 0x00000F00 /* bits 8 - 11 */
+/** This constant is a mask for the EF bits in the PSR. */
+#define SPARC_PSR_EF_MASK 0x00001000 /* bit 12 */
+/** This constant is a mask for the EC bits in the PSR. */
+#define SPARC_PSR_EC_MASK 0x00002000 /* bit 13 */
+/** This constant is a mask for the ICC bits in the PSR. */
+#define SPARC_PSR_ICC_MASK 0x00F00000 /* bits 20 - 23 */
+/** This constant is a mask for the VER bits in the PSR. */
+#define SPARC_PSR_VER_MASK 0x0F000000 /* bits 24 - 27 */
+/** This constant is a mask for the IMPL bits in the PSR. */
+#define SPARC_PSR_IMPL_MASK 0xF0000000 /* bits 28 - 31 */
+
+/** This constant is the starting bit position of the CWP in the PSR. */
+#define SPARC_PSR_CWP_BIT_POSITION 0 /* bits 0 - 4 */
+/** This constant is the starting bit position of the ET in the PSR. */
+#define SPARC_PSR_ET_BIT_POSITION 5 /* bit 5 */
+/** This constant is the starting bit position of the PS in the PSR. */
+#define SPARC_PSR_PS_BIT_POSITION 6 /* bit 6 */
+/** This constant is the starting bit position of the S in the PSR. */
+#define SPARC_PSR_S_BIT_POSITION 7 /* bit 7 */
+/** This constant is the starting bit position of the PIL in the PSR. */
+#define SPARC_PSR_PIL_BIT_POSITION 8 /* bits 8 - 11 */
+/** This constant is the starting bit position of the EF in the PSR. */
+#define SPARC_PSR_EF_BIT_POSITION 12 /* bit 12 */
+/** This constant is the starting bit position of the EC in the PSR. */
+#define SPARC_PSR_EC_BIT_POSITION 13 /* bit 13 */
+/** This constant is the starting bit position of the ICC in the PSR. */
+#define SPARC_PSR_ICC_BIT_POSITION 20 /* bits 20 - 23 */
+/** This constant is the starting bit position of the VER in the PSR. */
+#define SPARC_PSR_VER_BIT_POSITION 24 /* bits 24 - 27 */
+/** This constant is the starting bit position of the IMPL in the PSR. */
+#define SPARC_PSR_IMPL_BIT_POSITION 28 /* bits 28 - 31 */
+
+#define LEON3_ASR17_PROCESSOR_INDEX_SHIFT 28
+
+/* SPARC Software Trap number definitions */
+#define SPARC_SWTRAP_SYSCALL 0
+#define SPARC_SWTRAP_IRQDIS 9
+#define SPARC_SWTRAP_IRQEN 10
+#if SPARC_HAS_FPU == 1
+#define SPARC_SWTRAP_IRQDIS_FP 11
+#endif
+
+#ifndef ASM
+
+/**
+ * This macro is a standard nop instruction.
+ */
+#define nop() \
+ do { \
+ __asm__ volatile ( "nop" ); \
+ } while ( 0 )
+
+/**
+ * @brief Macro to obtain the PSR.
+ *
+ * This macro returns the current contents of the PSR register in @a _psr.
+ */
+#if defined(RTEMS_PARAVIRT)
+
+uint32_t _SPARC_Get_PSR( void );
+
+#define sparc_get_psr( _psr ) \
+ (_psr) = _SPARC_Get_PSR()
+
+#else /* RTEMS_PARAVIRT */
+
+#define sparc_get_psr( _psr ) \
+ do { \
+ (_psr) = 0; \
+ __asm__ volatile( "rd %%psr, %0" : "=r" (_psr) : "0" (_psr) ); \
+ } while ( 0 )
+
+#endif /* RTEMS_PARAVIRT */
+
+/**
+ * @brief Macro to set the PSR.
+ *
+ * This macro sets the PSR register to the value in @a _psr.
+ */
+#if defined(RTEMS_PARAVIRT)
+
+void _SPARC_Set_PSR( uint32_t new_psr );
+
+#define sparc_set_psr( _psr ) \
+ _SPARC_Set_PSR( _psr )
+
+#else /* RTEMS_PARAVIRT */
+
+#define sparc_set_psr( _psr ) \
+ do { \
+ __asm__ volatile ( "mov %0, %%psr " : "=r" ((_psr)) : "0" ((_psr)) ); \
+ nop(); \
+ nop(); \
+ nop(); \
+ } while ( 0 )
+
+#endif /* RTEMS_PARAVIRT */
+
+/**
+ * @brief Macro to obtain the TBR.
+ *
+ * This macro returns the current contents of the TBR register in @a _tbr.
+ */
+#if defined(RTEMS_PARAVIRT)
+
+uint32_t _SPARC_Get_TBR( void );
+
+#define sparc_get_tbr( _tbr ) \
+ (_tbr) = _SPARC_Get_TBR()
+
+#else /* RTEMS_PARAVIRT */
+
+#define sparc_get_tbr( _tbr ) \
+ do { \
+ (_tbr) = 0; /* to avoid unitialized warnings */ \
+ __asm__ volatile( "rd %%tbr, %0" : "=r" (_tbr) : "0" (_tbr) ); \
+ } while ( 0 )
+
+#endif /* RTEMS_PARAVIRT */
+
+/**
+ * @brief Macro to set the TBR.
+ *
+ * This macro sets the TBR register to the value in @a _tbr.
+ */
+#if defined(RTEMS_PARAVIRT)
+
+void _SPARC_Set_TBR( uint32_t new_tbr );
+
+#define sparc_set_tbr( _tbr ) \
+ _SPARC_Set_TBR((_tbr))
+
+#else /* RTEMS_PARAVIRT */
+
+#define sparc_set_tbr( _tbr ) \
+ do { \
+ __asm__ volatile( "wr %0, 0, %%tbr" : "=r" (_tbr) : "0" (_tbr) ); \
+ } while ( 0 )
+
+#endif /* RTEMS_PARAVIRT */
+
+/**
+ * @brief Macro to obtain the WIM.
+ *
+ * This macro returns the current contents of the WIM field in @a _wim.
+ */
+#define sparc_get_wim( _wim ) \
+ do { \
+ __asm__ volatile( "rd %%wim, %0" : "=r" (_wim) : "0" (_wim) ); \
+ } while ( 0 )
+
+/**
+ * @brief Macro to set the WIM.
+ *
+ * This macro sets the WIM field to the value in @a _wim.
+ */
+#define sparc_set_wim( _wim ) \
+ do { \
+ __asm__ volatile( "wr %0, %%wim" : "=r" (_wim) : "0" (_wim) ); \
+ nop(); \
+ nop(); \
+ nop(); \
+ } while ( 0 )
+
+/**
+ * @brief Macro to obtain the Y register.
+ *
+ * This macro returns the current contents of the Y register in @a _y.
+ */
+#define sparc_get_y( _y ) \
+ do { \
+ __asm__ volatile( "rd %%y, %0" : "=r" (_y) : "0" (_y) ); \
+ } while ( 0 )
+
+/**
+ * @brief Macro to set the Y register.
+ *
+ * This macro sets the Y register to the value in @a _y.
+ */
+#define sparc_set_y( _y ) \
+ do { \
+ __asm__ volatile( "wr %0, %%y" : "=r" (_y) : "0" (_y) ); \
+ } while ( 0 )
+
+/**
+ * @brief SPARC disable processor interrupts.
+ *
+ * This method is invoked to disable all maskable interrupts.
+ *
+ * @return This method returns the entire PSR contents.
+ */
+static inline uint32_t sparc_disable_interrupts(void)
+{
+ register uint32_t psr __asm__("g1"); /* return value of trap handler */
+ __asm__ volatile ( "ta %1\n\t" : "=r" (psr) : "i" (SPARC_SWTRAP_IRQDIS));
+ return psr;
+}
+
+/**
+ * @brief SPARC enable processor interrupts.
+ *
+ * This method is invoked to enable all maskable interrupts.
+ *
+ * @param[in] psr is the PSR returned by @ref sparc_disable_interrupts.
+ */
+static inline void sparc_enable_interrupts(uint32_t psr)
+{
+ register uint32_t _psr __asm__("g1") = psr; /* input to trap handler */
+
+ /*
+ * The trap instruction has a higher trap priority than the interrupts
+ * according to "The SPARC Architecture Manual: Version 8", Table 7-1
+ * "Exception and Interrupt Request Priority and tt Values". Add a nop to
+ * prevent a trap instruction right after the interrupt enable trap.
+ */
+ __asm__ volatile ( "ta %0\nnop\n" :: "i" (SPARC_SWTRAP_IRQEN), "r" (_psr));
+}
+
+/**
+ * @brief SPARC exit through system call 1
+ *
+ * This method is invoked to go into system error halt. The optional
+ * arguments can be given to hypervisor, hardware debugger, simulator or
+ * similar.
+ *
+ * System error mode is entered when taking a trap when traps have been
+ * disabled. What happens when error mode is entered depends on the motherboard.
+ * In a typical development systems the CPU relingish control to the debugger,
+ * simulator, hypervisor or similar. The following steps are taken:
+ *
+ * 1. Going into system error mode by Software Trap 0
+ * 2. %g1=1 (syscall 1 - Exit)
+ * 3. %g2=Primary exit code
+ * 4. %g3=Secondary exit code. Dependends on %g2 exit type.
+ *
+ * This function never returns.
+ *
+ * @param[in] exitcode1 Primary exit code stored in CPU g2 register after exit
+ * @param[in] exitcode2 Primary exit code stored in CPU g3 register after exit
+ */
+void sparc_syscall_exit(uint32_t exitcode1, uint32_t exitcode2)
+ RTEMS_NO_RETURN;
+
+/**
+ * @brief SPARC flash processor interrupts.
+ *
+ * This method is invoked to temporarily enable all maskable interrupts.
+ *
+ * @param[in] _psr is the PSR returned by @ref sparc_disable_interrupts.
+ */
+#define sparc_flash_interrupts( _psr ) \
+ do { \
+ sparc_enable_interrupts( (_psr) ); \
+ _psr = sparc_disable_interrupts(); \
+ } while ( 0 )
+
+/**
+ * @brief SPARC obtain interrupt level.
+ *
+ * This method is invoked to obtain the current interrupt disable level.
+ *
+ * @param[in] _level is the PSR returned by @ref sparc_disable_interrupts.
+ */
+#define sparc_get_interrupt_level( _level ) \
+ do { \
+ register uint32_t _psr_level = 0; \
+ \
+ sparc_get_psr( _psr_level ); \
+ (_level) = \
+ (_psr_level & SPARC_PSR_PIL_MASK) >> SPARC_PSR_PIL_BIT_POSITION; \
+ } while ( 0 )
+
+static inline uint32_t _LEON3_Get_current_processor( void )
+{
+ uint32_t asr17;
+
+ __asm__ volatile (
+ "rd %%asr17, %0"
+ : "=&r" (asr17)
+ );
+
+ return asr17 >> LEON3_ASR17_PROCESSOR_INDEX_SHIFT;
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_SPARC_H */
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h b/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h
new file mode 100644
index 0000000000..9f9999b063
--- /dev/null
+++ b/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_SPARCIMPL_H
+#define _RTEMS_SCORE_SPARCIMPL_H
+
+#include <rtems/score/cpu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * Provides a mutable alias to _SPARC_Counter for use in
+ * _SPARC_Counter_initialize(). The _SPARC_Counter and _SPARC_Counter_mutable
+ * are defined via the SPARC_COUNTER_DEFINITION define.
+ */
+extern SPARC_Counter _SPARC_Counter_mutable;
+
+CPU_Counter_ticks _SPARC_Counter_read_address( void );
+
+CPU_Counter_ticks _SPARC_Counter_read_asr23( void );
+
+CPU_Counter_ticks _SPARC_Counter_difference_normal(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+);
+
+CPU_Counter_ticks _SPARC_Counter_difference_clock_period(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+);
+
+/*
+ * Returns always a value of one regardless of the parameters. This prevents
+ * an infinite loop in rtems_counter_delay_ticks(). Its only a reasonably safe
+ * default.
+ */
+CPU_Counter_ticks _SPARC_Counter_difference_one(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+);
+
+static inline void _SPARC_Counter_initialize(
+ SPARC_Counter_read counter_read,
+ SPARC_Counter_difference counter_difference,
+ volatile const CPU_Counter_ticks *counter_address
+)
+{
+ _SPARC_Counter_mutable.counter_read = counter_read;
+ _SPARC_Counter_mutable.counter_difference = counter_difference;
+ _SPARC_Counter_mutable.counter_address = counter_address;
+}
+
+/*
+ * Defines the _SPARC_Counter and _SPARC_Counter_mutable global variables.
+ * Place this define in the global file scope of the CPU counter support file
+ * of the BSP.
+ */
+#define SPARC_COUNTER_DEFINITION \
+ __asm__ ( \
+ "\t.global\t_SPARC_Counter\n" \
+ "\t.global\t_SPARC_Counter_mutable\n" \
+ "\t.section\t.data._SPARC_Counter,\"aw\",@progbits\n" \
+ "\t.align\t4\n" \
+ "\t.type\t_SPARC_Counter, #object\n" \
+ "\t.size\t_SPARC_Counter, 12\n" \
+ "_SPARC_Counter:\n" \
+ "_SPARC_Counter_mutable:\n" \
+ "\t.long\t_SPARC_Counter_read_address\n" \
+ "\t.long\t_SPARC_Counter_difference_one\n" \
+ "\t.long\t_SPARC_Counter\n" \
+ )
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SPARCIMPL_H */
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/types.h b/cpukit/score/cpu/sparc/include/rtems/score/types.h
new file mode 100644
index 0000000000..6419c9f15f
--- /dev/null
+++ b/cpukit/score/cpu/sparc/include/rtems/score/types.h
@@ -0,0 +1,53 @@
+/**
+ * @file
+ *
+ * @brief SPARC CPU Type Definitions
+ *
+ * This include file contains type definitions pertaining to the
+ * SPARC processor family.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_TYPES_H
+#define _RTEMS_SCORE_TYPES_H
+
+#include <rtems/score/basedefs.h>
+
+#ifndef ASM
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Type that can store a 32-bit integer or a pointer. */
+typedef uintptr_t CPU_Uint32ptr;
+
+/**
+ * @brief SPARC ISR handler return type.
+ *
+ * This is the type which SPARC ISR Handlers return.
+ */
+typedef void sparc_isr;
+
+/**
+ * @brief SPARC ISR handler prototype.
+ *
+ * This is the prototype for SPARC ISR Handlers.
+ */
+typedef void ( *sparc_isr_entry )( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif