RTEMS
|
SPARC CPU Department Source. More...
Go to the source code of this file.
Classes | |
struct | SPARC_Minimum_stack_frame |
struct | Context_Control |
SPARC basic context. More... | |
struct | Context_Control_fp |
SPARC basic context. More... | |
struct | CPU_Interrupt_frame |
Interrupt stack frame (ISF). More... | |
struct | CPU_Trap_table_entry |
struct | CPU_Exception_frame |
struct | SPARC_Counter |
Macros | |
#define | CPU_SIMPLE_VECTORED_INTERRUPTS TRUE |
#define | CPU_ISR_PASSES_FRAME_POINTER FALSE |
#define | CPU_HARDWARE_FP FALSE |
#define | CPU_SOFTWARE_FP FALSE |
#define | CPU_ALL_TASKS_ARE_FP FALSE |
#define | CPU_IDLE_TASK_IS_FP FALSE |
#define | CPU_USE_DEFERRED_FP_SWITCH FALSE |
#define | CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE |
#define | CPU_STACK_GROWS_UP FALSE |
#define | CPU_CACHE_LINE_BYTES 64 |
#define | CPU_STRUCTURE_ALIGNMENT RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES ) |
#define | CPU_MODES_INTERRUPT_MASK 0x0000000F |
#define | CPU_STACK_FRAME_L0_OFFSET 0x00 |
#define | CPU_STACK_FRAME_L1_OFFSET 0x04 |
#define | CPU_STACK_FRAME_L2_OFFSET 0x08 |
#define | CPU_STACK_FRAME_L3_OFFSET 0x0c |
#define | CPU_STACK_FRAME_L4_OFFSET 0x10 |
#define | CPU_STACK_FRAME_L5_OFFSET 0x14 |
#define | CPU_STACK_FRAME_L6_OFFSET 0x18 |
#define | CPU_STACK_FRAME_L7_OFFSET 0x1c |
#define | CPU_STACK_FRAME_I0_OFFSET 0x20 |
#define | CPU_STACK_FRAME_I1_OFFSET 0x24 |
#define | CPU_STACK_FRAME_I2_OFFSET 0x28 |
#define | CPU_STACK_FRAME_I3_OFFSET 0x2c |
#define | CPU_STACK_FRAME_I4_OFFSET 0x30 |
#define | CPU_STACK_FRAME_I5_OFFSET 0x34 |
#define | CPU_STACK_FRAME_I6_FP_OFFSET 0x38 |
#define | CPU_STACK_FRAME_I7_OFFSET 0x3c |
#define | CPU_STRUCTURE_RETURN_ADDRESS_OFFSET 0x40 |
#define | CPU_STACK_FRAME_SAVED_ARG0_OFFSET 0x44 |
#define | CPU_STACK_FRAME_SAVED_ARG1_OFFSET 0x48 |
#define | CPU_STACK_FRAME_SAVED_ARG2_OFFSET 0x4c |
#define | CPU_STACK_FRAME_SAVED_ARG3_OFFSET 0x50 |
#define | CPU_STACK_FRAME_SAVED_ARG4_OFFSET 0x54 |
#define | CPU_STACK_FRAME_SAVED_ARG5_OFFSET 0x58 |
#define | CPU_STACK_FRAME_PAD0_OFFSET 0x5c |
#define | CPU_MAXIMUM_PROCESSORS 32 |
#define | _CPU_Context_Get_SP(_context) (_context)->o6_sp |
#define | G5_OFFSET 0x00 |
#define | G7_OFFSET 0x04 |
#define | L0_OFFSET 0x08 |
#define | L1_OFFSET 0x0C |
#define | L2_OFFSET 0x10 |
#define | L3_OFFSET 0x14 |
#define | L4_OFFSET 0x18 |
#define | L5_OFFSET 0x1C |
#define | L6_OFFSET 0x20 |
#define | L7_OFFSET 0x24 |
#define | I0_OFFSET 0x28 |
#define | I1_OFFSET 0x2C |
#define | I2_OFFSET 0x30 |
#define | I3_OFFSET 0x34 |
#define | I4_OFFSET 0x38 |
#define | I5_OFFSET 0x3C |
#define | I6_FP_OFFSET 0x40 |
#define | I7_OFFSET 0x44 |
#define | O6_SP_OFFSET 0x48 |
#define | O7_OFFSET 0x4C |
#define | PSR_OFFSET 0x50 |
#define | ISR_DISPATCH_DISABLE_STACK_OFFSET 0x54 |
#define | SPARC_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 0x58 |
#define | FO_F1_OFFSET 0x00 |
#define | F2_F3_OFFSET 0x08 |
#define | F4_F5_OFFSET 0x10 |
#define | F6_F7_OFFSET 0x18 |
#define | F8_F9_OFFSET 0x20 |
#define | F1O_F11_OFFSET 0x28 |
#define | F12_F13_OFFSET 0x30 |
#define | F14_F15_OFFSET 0x38 |
#define | F16_F17_OFFSET 0x40 |
#define | F18_F19_OFFSET 0x48 |
#define | F2O_F21_OFFSET 0x50 |
#define | F22_F23_OFFSET 0x58 |
#define | F24_F25_OFFSET 0x60 |
#define | F26_F27_OFFSET 0x68 |
#define | F28_F29_OFFSET 0x70 |
#define | F3O_F31_OFFSET 0x78 |
#define | FSR_OFFSET 0x80 |
#define | CONTEXT_CONTROL_FP_SIZE 0x84 |
#define | CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp ) |
#define | CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 1024 |
#define | CPU_INTERRUPT_NUMBER_OF_VECTORS 256 |
#define | CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER 511 |
#define | SPARC_SYNCHRONOUS_TRAP_BIT_MASK 0x100 |
#define | SPARC_ASYNCHRONOUS_TRAP(_trap) (_trap) |
#define | SPARC_SYNCHRONOUS_TRAP(_trap) ((_trap) + 256 ) |
#define | SPARC_REAL_TRAP_NUMBER(_trap) ((_trap) % 256) |
#define | CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE |
#define | CPU_STACK_MINIMUM_SIZE (1024*4) |
#define | CPU_SIZEOF_POINTER 4 |
#define | CPU_ALIGNMENT 8 |
#define | CPU_HEAP_ALIGNMENT CPU_ALIGNMENT |
#define | CPU_STACK_ALIGNMENT CPU_ALIGNMENT |
#define | CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES |
#define | _CPU_Initialize_vectors() |
#define | _CPU_ISR_Disable(_level) (_level) = sparc_disable_interrupts() |
#define | _CPU_ISR_Enable(_level) sparc_enable_interrupts( _level ) |
#define | _CPU_ISR_Flash(_level) sparc_flash_interrupts( _level ) |
#define | _CPU_ISR_Is_enabled(_isr_cookie) sparc_interrupt_is_enabled( _isr_cookie ) |
#define | _CPU_ISR_Set_level(_newlevel) sparc_enable_interrupts( _newlevel << 8) |
#define | _CPU_Context_Initialization_at_thread_begin() |
#define | _CPU_Context_Restart_self(_the_context) _CPU_Context_restore( (_the_context) ); |
#define | _CPU_Context_Initialize_fp(_destination) do { } while ( 0 ) |
Nothing to do due to the synchronous or lazy floating point switch. | |
#define | _CPU_Context_save_fp(_fp_context_ptr) do { } while ( 0 ) |
Nothing to do due to the synchronous or lazy floating point switch. | |
#define | _CPU_Context_restore_fp(_fp_context_ptr) do { } while ( 0 ) |
Nothing to do due to the synchronous or lazy floating point switch. | |
#define | CPU_USE_LIBC_INIT_FINI_ARRAY FALSE |
#define | CPU_USE_GENERIC_BITFIELD_CODE TRUE |
#define | CPU_swap_u16(value) (((value&0xff) << 8) | ((value >> 8)&0xff)) |
SPARC specific method to endian swap an uint16_t. More... | |
Typedefs | |
typedef struct Context_Control_fp | Context_Control_fp |
typedef void(* | CPU_ISR_raw_handler) (void) |
typedef void(* | CPU_ISR_handler) (uint32_t) |
typedef uint32_t | CPU_Counter_ticks |
typedef CPU_Counter_ticks(* | SPARC_Counter_read) (void) |
typedef uintptr_t | CPU_Uint32ptr |
Functions | |
static bool | _CPU_Context_Get_is_executing (const Context_Control *context) |
static void | _CPU_Context_Set_is_executing (Context_Control *context, bool is_executing) |
static __inline__ bool | _CPU_ISR_Is_enabled (uint32_t level) |
uint32_t | _CPU_ISR_Get_level (void) |
Obtain the current interrupt disable level. More... | |
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) |
void | _CPU_Fatal_halt (uint32_t source, uint32_t error) RTEMS_NO_RETURN |
void | _CPU_Initialize (void) |
SPARC specific initialization. More... | |
void | _CPU_ISR_install_raw_handler (uint32_t vector, CPU_ISR_raw_handler new_handler, CPU_ISR_raw_handler *old_handler) |
SPARC specific raw ISR installer. More... | |
void | _CPU_ISR_install_vector (uint32_t vector, CPU_ISR_handler new_handler, CPU_ISR_handler *old_handler) |
SPARC specific RTEMS ISR installer. More... | |
void * | _CPU_Thread_Idle_body (uintptr_t ignored) |
void | _CPU_Context_switch (Context_Control *run, Context_Control *heir) |
SPARC specific context switch. More... | |
void | _CPU_Context_restore (Context_Control *new_context) RTEMS_NO_RETURN |
SPARC specific context restore. More... | |
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) |
uint32_t | _CPU_SMP_Get_current_processor (void) |
void | _CPU_SMP_Send_interrupt (uint32_t target_processor_index) |
static void | _CPU_SMP_Processor_event_broadcast (void) |
static void | _CPU_SMP_Processor_event_receive (void) |
void | _CPU_Exception_frame_print (const CPU_Exception_frame *frame) |
static uint32_t | CPU_swap_u32 (uint32_t value) |
SPARC specific method to endian swap an uint32_t. More... | |
uint32_t | _CPU_Counter_frequency (void) |
static CPU_Counter_ticks | _CPU_Counter_read (void) |
static CPU_Counter_ticks | _CPU_Counter_difference (CPU_Counter_ticks second, CPU_Counter_ticks first) |
Variables | |
const CPU_Trap_table_entry | _CPU_Trap_slot_template |
const SPARC_Counter | _SPARC_Counter |
SPARC CPU Department Source.
This include file contains information pertaining to the port of the executive to the SPARC processor.
Definition in file cpu.h.
#define _CPU_Context_Initialization_at_thread_begin | ( | ) |
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_Restart_self | ( | _the_context | ) | _CPU_Context_restore( (_the_context) ); |
#define _CPU_Initialize_vectors | ( | ) |
#define _CPU_ISR_Disable | ( | _level | ) | (_level) = sparc_disable_interrupts() |
#define _CPU_ISR_Enable | ( | _level | ) | sparc_enable_interrupts( _level ) |
#define _CPU_ISR_Flash | ( | _level | ) | sparc_flash_interrupts( _level ) |
#define _CPU_ISR_Set_level | ( | _newlevel | ) | sparc_enable_interrupts( _newlevel << 8) |
#define CPU_ALIGNMENT 8 |
#define CPU_ALL_TASKS_ARE_FP FALSE |
#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp ) |
#define CPU_HARDWARE_FP FALSE |
#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT |
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_IDLE_TASK_IS_FP FALSE |
Should the IDLE task have a floating point context?
The IDLE task does not have to be floating point on the SPARC.
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER 511 |
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256 |
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_ISR_PASSES_FRAME_POINTER FALSE |
#define CPU_MODES_INTERRUPT_MASK 0x0000000F |
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_MPCI_RECEIVE_SERVER_EXTRA_STACK 1024 |
#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE |
#define CPU_SIMPLE_VECTORED_INTERRUPTS TRUE |
Does the CPU follow the simple vectored interrupt model?
THe SPARC is a simple vectored architecture. Usually there is no PIC and the CPU directly vectors the interrupts.
#define CPU_SIZEOF_POINTER 4 |
#define CPU_SOFTWARE_FP FALSE |
#define CPU_STACK_ALIGNMENT CPU_ALIGNMENT |
#define CPU_STACK_FRAME_I0_OFFSET 0x20 |
#define CPU_STACK_FRAME_I1_OFFSET 0x24 |
#define CPU_STACK_FRAME_I2_OFFSET 0x28 |
#define CPU_STACK_FRAME_I3_OFFSET 0x2c |
#define CPU_STACK_FRAME_I4_OFFSET 0x30 |
#define CPU_STACK_FRAME_I5_OFFSET 0x34 |
#define CPU_STACK_FRAME_I6_FP_OFFSET 0x38 |
#define CPU_STACK_FRAME_I7_OFFSET 0x3c |
#define CPU_STACK_FRAME_L0_OFFSET 0x00 |
#define CPU_STACK_FRAME_L1_OFFSET 0x04 |
#define CPU_STACK_FRAME_L2_OFFSET 0x08 |
#define CPU_STACK_FRAME_L3_OFFSET 0x0c |
#define CPU_STACK_FRAME_L4_OFFSET 0x10 |
#define CPU_STACK_FRAME_L5_OFFSET 0x14 |
#define CPU_STACK_FRAME_L6_OFFSET 0x18 |
#define CPU_STACK_FRAME_L7_OFFSET 0x1c |
#define CPU_STACK_FRAME_PAD0_OFFSET 0x5c |
#define CPU_STACK_FRAME_SAVED_ARG0_OFFSET 0x44 |
#define CPU_STACK_FRAME_SAVED_ARG1_OFFSET 0x48 |
#define CPU_STACK_FRAME_SAVED_ARG2_OFFSET 0x4c |
#define CPU_STACK_FRAME_SAVED_ARG3_OFFSET 0x50 |
#define CPU_STACK_FRAME_SAVED_ARG4_OFFSET 0x54 |
#define CPU_STACK_FRAME_SAVED_ARG5_OFFSET 0x58 |
#define CPU_STACK_GROWS_UP FALSE |
#define CPU_STACK_MINIMUM_SIZE (1024*4) |
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_STRUCTURE_RETURN_ADDRESS_OFFSET 0x40 |
#define CPU_swap_u16 | ( | value | ) | (((value&0xff) << 8) | ((value >> 8)&0xff)) |
#define CPU_USE_GENERIC_BITFIELD_CODE TRUE |
#define SPARC_ASYNCHRONOUS_TRAP | ( | _trap | ) | (_trap) |
#define SPARC_REAL_TRAP_NUMBER | ( | _trap | ) | ((_trap) % 256) |
#define SPARC_SYNCHRONOUS_TRAP | ( | _trap | ) | ((_trap) + 256 ) |
#define SPARC_SYNCHRONOUS_TRAP_BIT_MASK 0x100 |
typedef uintptr_t CPU_Uint32ptr |
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 | ||
) |
Initialize the context to a state suitable for starting a task after a context restore operation. Generally, this involves:
[in] | the_context | points to the context area |
[in] | stack_base | is the low address of the allocated stack area |
[in] | size | is the size of the stack area in bytes |
[in] | new_level | is the interrupt level for the task |
[in] | entry_point | is the task's entry point |
[in] | is_fp | is set to TRUE if the task is a floating point task |
[in] | tls_area | is the thread-local storage (TLS) area |
NOTE: Implemented as a subroutine for the SPARC port.
void _CPU_Context_restore | ( | Context_Control * | new_context | ) |
SPARC specific context restore.
This routine is generally used only to restart self in an efficient manner.
[in] | new_context | is the context to restore |
void _CPU_Context_switch | ( | Context_Control * | run, |
Context_Control * | heir | ||
) |
SPARC specific context switch.
This routine switches from the run context to the heir context.
[in] | run | is the currently executing thread |
[in] | heir | will become the currently executing thread |
void _CPU_Fatal_halt | ( | uint32_t | source, |
uint32_t | error | ||
) |
This routine copies _error into a known place – typically a stack location or a register, optionally disables interrupts, and halts/stops the CPU.
Definition at line 31 of file bsp_fatal_halt.c.
void _CPU_Initialize | ( | void | ) |
uint32_t _CPU_ISR_Get_level | ( | void | ) |
void _CPU_ISR_install_raw_handler | ( | uint32_t | vector, |
CPU_ISR_raw_handler | new_handler, | ||
CPU_ISR_raw_handler * | old_handler | ||
) |
void _CPU_ISR_install_vector | ( | uint32_t | vector, |
CPU_ISR_handler | new_handler, | ||
CPU_ISR_handler * | old_handler | ||
) |
|
inlinestatic |
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.
[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.
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).
const CPU_Trap_table_entry _CPU_Trap_slot_template |
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.