SPARC port passes all tests

This commit is contained in:
Joel Sherrill
1995-10-30 21:54:45 +00:00
parent ea744828ad
commit 97005786d8
112 changed files with 4355 additions and 1359 deletions
+2 -1
View File
@@ -68,7 +68,8 @@ The following persons/organizations have made contributions:
to port RTEMS to the SPARC V7 architecture for use with their ERC32
radiation-hardened CPU. Jiri Gaisler (jgais@wd.estec.esa.nl) deserves
special thanks for championing this port within the ESA was well as
for developing the SPARC Instruction Simulator used to test this port.
for developing and supporting the SPARC Instruction Simulator used to
develop and test this port.
Finally, the RTEMS project would like to thank those who have contributed
to the other free software efforts which RTEMS utilizes. The primary RTEMS
+18 -7
View File
@@ -10,13 +10,13 @@
#define __RINGBUF_H__
#ifndef RINGBUF_QUEUE_LENGTH
#define RINGBUF_QUEUE_LENGTH 200
#define RINGBUF_QUEUE_LENGTH 128
#endif
typedef struct {
char buffer[RINGBUF_QUEUE_LENGTH];
int head;
int tail;
volatile int head;
volatile int tail;
} Ring_buffer_t;
#define Ring_buffer_Initialize( _buffer ) \
@@ -27,16 +27,27 @@ typedef struct {
#define Ring_buffer_Is_empty( _buffer ) \
( (_buffer)->head == (_buffer)->tail )
#define Ring_buffer_Is_full( _buffer ) \
( (_buffer)->head == ((_buffer)->tail + 1) % RINGBUF_QUEUE_LENGTH )
#define Ring_buffer_Add_character( _buffer, _ch ) \
do { \
(_buffer)->buffer[ (_buffer)->tail ] = (_ch); \
(_buffer)->tail = ((_buffer)->tail+1) % RINGBUF_QUEUE_LENGTH; \
rtems_unsigned32 isrlevel; \
\
rtems_interrupt_disable( isrlevel ); \
(_buffer)->tail = ((_buffer)->tail+1) % RINGBUF_QUEUE_LENGTH; \
(_buffer)->buffer[ (_buffer)->tail ] = (_ch); \
rtems_interrupt_enable( isrlevel ); \
} while ( 0 )
#define Ring_buffer_Remove_character( _buffer, _ch ) \
do { \
(_ch) = (_buffer)->buffer[ (_buffer)->head ]; \
(_buffer)->head = ((_buffer)->head+1) % RINGBUF_QUEUE_LENGTH; \
rtems_unsigned32 isrlevel; \
\
rtems_interrupt_disable( isrlevel ); \
(_buffer)->head = ((_buffer)->head+1) % RINGBUF_QUEUE_LENGTH; \
(_ch) = (_buffer)->buffer[ (_buffer)->head ]; \
rtems_interrupt_enable( isrlevel ); \
} while ( 0 )
#endif
+1 -2
View File
@@ -60,8 +60,7 @@ EXTERN Objects_Information _POSIX_Interrupt_Handlers_Information;
* interrupt handlers installed on each vector.
*/
EXTERN POSIX_Interrupt_Control
_POSIX_Interrupt_Information[ ISR_NUMBER_OF_VECTORS ];
EXTERN POSIX_Interrupt_Control _POSIX_Interrupt_Information[ ISR_NUMBER_OF_VECTORS ];
/*
* _POSIX_Interrupt_Manager_initialization
+1 -2
View File
@@ -60,8 +60,7 @@ EXTERN Objects_Information _POSIX_Interrupt_Handlers_Information;
* interrupt handlers installed on each vector.
*/
EXTERN POSIX_Interrupt_Control
_POSIX_Interrupt_Information[ ISR_NUMBER_OF_VECTORS ];
EXTERN POSIX_Interrupt_Control _POSIX_Interrupt_Information[ ISR_NUMBER_OF_VECTORS ];
/*
* _POSIX_Interrupt_Manager_initialization
+202
View File
@@ -108,3 +108,205 @@ rtems_status_code rtems_event_receive(
_Thread_Enable_dispatch();
return( _Thread_Executing->Wait.return_code );
}
/*PAGE
*
* _Event_Seize
*
* This routine attempts to satisfy the requested event condition
* for the running thread.
*
* Input parameters:
* event_in - the event condition to satisfy
* option_set - acquire event options
* ticks - interval to wait
* event_out - pointer to event set output area
*
* Output parameters: NONE
* *event_out - event set output area filled in
*
* INTERRUPT LATENCY:
* available
* wait
* check sync
*/
void _Event_Seize(
rtems_event_set event_in,
rtems_option option_set,
rtems_interval ticks,
rtems_event_set *event_out
)
{
Thread_Control *executing;
rtems_event_set seized_events;
rtems_event_set pending_events;
ISR_Level level;
RTEMS_API_Control *api;
executing = _Thread_Executing;
executing->Wait.return_code = RTEMS_SUCCESSFUL;
api = executing->API_Extensions[ THREAD_API_RTEMS ];
_ISR_Disable( level );
pending_events = api->pending_events;
seized_events = _Event_sets_Get( pending_events, event_in );
if ( !_Event_sets_Is_empty( seized_events ) &&
(seized_events == event_in || _Options_Is_any( option_set )) ) {
api->pending_events =
_Event_sets_Clear( pending_events, seized_events );
_ISR_Enable( level );
*event_out = seized_events;
return;
}
if ( _Options_Is_no_wait( option_set ) ) {
_ISR_Enable( level );
executing->Wait.return_code = RTEMS_UNSATISFIED;
*event_out = seized_events;
return;
}
_Event_Sync = TRUE;
executing->Wait.option = (unsigned32) option_set;
executing->Wait.count = (unsigned32) event_in;
executing->Wait.return_argument = event_out;
_ISR_Enable( level );
_Thread_Set_state( executing, STATES_WAITING_FOR_EVENT );
if ( ticks ) {
_Watchdog_Initialize(
&executing->Timer,
_Event_Timeout,
executing->Object.id,
NULL
);
_Watchdog_Insert_ticks(
&executing->Timer,
ticks,
WATCHDOG_NO_ACTIVATE
);
}
_ISR_Disable( level );
if ( _Event_Sync == TRUE ) {
_Event_Sync = FALSE;
if ( ticks )
_Watchdog_Activate( &executing->Timer );
_ISR_Enable( level );
return;
}
_ISR_Enable( level );
(void) _Watchdog_Remove( &executing->Timer );
_Thread_Unblock( executing );
return;
}
/*PAGE
*
* _Event_Surrender
*
* This routines remove a thread from the specified threadq.
*
* Input parameters:
* the_thread - pointer to thread to be dequeued
*
* Output parameters: NONE
*
* INTERRUPT LATENCY:
* before flash
* after flash
* check sync
*/
void _Event_Surrender(
Thread_Control *the_thread
)
{
ISR_Level level;
rtems_event_set pending_events;
rtems_event_set event_condition;
rtems_event_set seized_events;
rtems_option option_set;
RTEMS_API_Control *api;
api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
option_set = (rtems_option) the_thread->Wait.option;
_ISR_Disable( level );
pending_events = api->pending_events;
event_condition = (rtems_event_set) the_thread->Wait.count;
seized_events = _Event_sets_Get( pending_events, event_condition );
if ( !_Event_sets_Is_empty( seized_events ) ) {
if ( _States_Is_waiting_for_event( the_thread->current_state ) ) {
if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
api->pending_events =
_Event_sets_Clear( pending_events, seized_events );
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
_ISR_Flash( level );
if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
_ISR_Enable( level );
_Thread_Unblock( the_thread );
}
else {
_Watchdog_Deactivate( &the_thread->Timer );
_ISR_Enable( level );
(void) _Watchdog_Remove( &the_thread->Timer );
_Thread_Unblock( the_thread );
}
return;
}
}
else if ( _Thread_Is_executing( the_thread ) && _Event_Sync == TRUE ) {
if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
api->pending_events = _Event_sets_Clear( pending_events,seized_events );
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
_Event_Sync = FALSE;
}
}
}
_ISR_Enable( level );
}
/*PAGE
*
* _Event_Timeout
*
* This routine processes a thread which timeouts while waiting to
* receive an event_set. It is called by the watchdog handler.
*
* Input parameters:
* id - thread id
*
* Output parameters: NONE
*/
void _Event_Timeout(
Objects_Id id,
void *ignored
)
{
Thread_Control *the_thread;
Objects_Locations location;
the_thread = _Thread_Get( id, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE: /* impossible */
break;
case OBJECTS_LOCAL:
the_thread->Wait.return_code = RTEMS_TIMEOUT;
_Thread_Unblock( the_thread );
_Thread_Unnest_dispatch();
break;
}
}
+7 -3
View File
@@ -278,7 +278,8 @@ EXTERN void *_CPU_Interrupt_stack_high;
* interrupts (genie, rhino, etc)
*/
#define CPU_INTERRUPT_NUMBER_OF_VECTORS (HPPA_INTERRUPT_MAX)
#define CPU_INTERRUPT_NUMBER_OF_VECTORS (HPPA_INTERRUPT_MAX)
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
/*
* Don't be chintzy here; we don't want to debug these problems
@@ -387,7 +388,7 @@ unsigned32 _CPU_ISR_Get_level( void );
*/
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
_new_level, _entry_point ) \
_new_level, _entry_point, _is_fp ) \
do { \
unsigned32 _stack; \
\
@@ -456,6 +457,9 @@ void hppa_cpu_halt(unsigned32 type_of_halt, unsigned32 the_error);
* is implemented in software.
*/
#define CPU_USE_GENERIC_BITFIELD_CODE FALSE
#define CPU_USE_GENERIC_BITFIELD_DATA FALSE
int hppa_rtems_ffs(unsigned int value);
#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
_output = hppa_rtems_ffs(_value)
@@ -477,7 +481,7 @@ int hppa_rtems_ffs(unsigned int value);
#define _CPU_Priority_Mask( _bit_number ) \
( 1 << (_bit_number) )
#define _CPU_Priority_Bits_index( _priority ) \
#define _CPU_Priority_bits_index( _priority ) \
(_priority)
/* end of Priority handler macros */
+7 -3
View File
@@ -143,7 +143,8 @@ EXTERN void *_CPU_Interrupt_stack_high;
* i386 family supports 256 distinct vectors.
*/
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
/*
* Minimum size of a thread's stack.
@@ -208,7 +209,7 @@ unsigned32 _CPU_ISR_Get_level( void );
#define CPU_EFLAGS_INTERRUPTS_OFF 0x00003002
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
_isr, _entry_point ) \
_isr, _entry_point, _is_fp ) \
do { \
unsigned32 _stack; \
\
@@ -265,6 +266,9 @@ unsigned32 _CPU_ISR_Get_level( void );
* + scan for the highest numbered (MSB) set in a 16 bit bitfield
*/
#define CPU_USE_GENERIC_BITFIELD_CODE FALSE
#define CPU_USE_GENERIC_BITFIELD_DATA FALSE
#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
{ \
register unsigned16 __value_in_register = (_value); \
@@ -292,7 +296,7 @@ unsigned32 _CPU_ISR_Get_level( void );
#define _CPU_Priority_Mask( _bit_number ) \
( 1 << (_bit_number) )
#define _CPU_Priority_Bits_index( _priority ) \
#define _CPU_Priority_bits_index( _priority ) \
(_priority)
/* functions */
+7 -3
View File
@@ -185,7 +185,8 @@ EXTERN void *_CPU_Interrupt_stack_high;
* i960 family supports 256 distinct vectors.
*/
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
/*
* Minimum size of a thread's stack.
@@ -252,7 +253,7 @@ unsigned32 _CPU_ISR_Get_level( void );
*/
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
_isr, _entry ) \
_isr, _entry, _is_fp ) \
{ CPU_Call_frame *_texit_frame; \
unsigned32 _mask; \
unsigned32 _base_pc; \
@@ -318,6 +319,9 @@ unsigned32 _CPU_ISR_Get_level( void );
* + scan for the highest numbered (MSB) set in a 16 bit bitfield
*/
#define CPU_USE_GENERIC_BITFIELD_CODE FALSE
#define CPU_USE_GENERIC_BITFIELD_DATA FALSE
#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
{ unsigned32 _search = (_value); \
\
@@ -341,7 +345,7 @@ unsigned32 _CPU_ISR_Get_level( void );
#define _CPU_Priority_Mask( _bit_number ) \
( 0x8000 >> (_bit_number) )
#define _CPU_Priority_Bits_index( _priority ) \
#define _CPU_Priority_bits_index( _priority ) \
( 15 - (_priority) )
/* end of Priority handler macros */
+8 -4
View File
@@ -175,7 +175,8 @@ extern char _VBR[];
* m68k family supports 256 distinct vectors.
*/
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
/*
* Minimum size of a thread's stack.
@@ -237,7 +238,7 @@ unsigned32 _CPU_ISR_Get_level( void );
*/
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
_isr, _entry_point ) \
_isr, _entry_point, _is_fp ) \
do { \
void *_stack; \
\
@@ -301,6 +302,9 @@ unsigned32 _CPU_ISR_Get_level( void );
* have a real 16 bit wide bitfield which operates "correctly."
*/
#define CPU_USE_GENERIC_BITFIELD_CODE FALSE
#define CPU_USE_GENERIC_BITFIELD_DATA FALSE
#if ( M68K_HAS_BFFFO == 1 )
#ifdef NO_UNINITIALIZED_WARNINGS
@@ -327,7 +331,7 @@ unsigned32 _CPU_ISR_Get_level( void );
#else
/* duplicates BFFFO results for 16 bits (i.e., 15-(_priority) in
_CPU_Priority_Bits_index is not needed), handles the 0 case, and
_CPU_Priority_bits_index is not needed), handles the 0 case, and
does not molest _value -- jsg */
#ifndef m68000
#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
@@ -386,7 +390,7 @@ unsigned32 _CPU_ISR_Get_level( void );
#define _CPU_Priority_Mask( _bit_number ) \
( 0x8000 >> (_bit_number) )
#define _CPU_Priority_Bits_index( _priority ) \
#define _CPU_Priority_bits_index( _priority ) \
(_priority)
/* end of Priority handler macros */
-3
View File
@@ -174,9 +174,6 @@ SYM (_ISR_Handler):
* in place to know what vector we got on a 68000 core.
*/
.global SYM (_ISR_Exit)
SYM (_ISR_Exit):
subql #1,SYM (_ISR_Nest_level) | one less nest level
subql #1,SYM (_Thread_Dispatch_disable_level)
| unnest multitasking
+21 -5
View File
@@ -412,7 +412,8 @@ EXTERN void (*_CPU_Thread_dispatch_pointer)();
* by RTEMS.
*/
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 32
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 32
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
/*
* Should be large enough to run all RTEMS tests. This insures
@@ -536,7 +537,7 @@ EXTERN void (*_CPU_Thread_dispatch_pointer)();
*/
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
_isr, _entry_point ) \
_isr, _entry_point, _is_fp ) \
{ \
}
@@ -621,11 +622,11 @@ EXTERN void (*_CPU_Thread_dispatch_pointer)();
*
* RTEMS guarantees that (1) will never happen so it is not a concern.
* (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
* _CPU_Priority_Bits_index(). These three form a set of routines
* _CPU_Priority_bits_index(). These three form a set of routines
* which must logically operate together. Bits in the _value are
* set and cleared based on masks built by _CPU_Priority_mask().
* The basic major and minor values calculated by _Priority_Major()
* and _Priority_Minor() are "massaged" by _CPU_Priority_Bits_index()
* and _Priority_Minor() are "massaged" by _CPU_Priority_bits_index()
* to properly range between the values returned by the "find first bit"
* instruction. This makes it possible for _Priority_Get_highest() to
* calculate the major and directly index into the minor table.
@@ -660,11 +661,18 @@ EXTERN void (*_CPU_Thread_dispatch_pointer)();
* bit set
*/
#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
{ \
(_output) = 0; /* do something to prevent warnings */ \
}
#endif
/* end of Bitfield handler macros */
/*
@@ -673,9 +681,13 @@ EXTERN void (*_CPU_Thread_dispatch_pointer)();
* for that routine.
*/
#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
#define _CPU_Priority_Mask( _bit_number ) \
( 1 << (_bit_number) )
#endif
/*
* This routine translates the bit numbers returned by
* _CPU_Bitfield_Find_first_bit() into something suitable for use as
@@ -683,9 +695,13 @@ EXTERN void (*_CPU_Thread_dispatch_pointer)();
* for that routine.
*/
#define _CPU_Priority_Bits_index( _priority ) \
#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
#define _CPU_Priority_bits_index( _priority ) \
(_priority)
#endif
/* end of Priority handler macros */
/* functions */
+9 -5
View File
@@ -541,7 +541,8 @@ EXTERN struct {
* by RTEMS.
*/
#define CPU_INTERRUPT_NUMBER_OF_VECTORS (PPC_INTERRUPT_MAX)
#define CPU_INTERRUPT_NUMBER_OF_VECTORS (PPC_INTERRUPT_MAX)
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
/*
* Should be large enough to run all RTEMS tests. This insures
@@ -682,7 +683,7 @@ EXTERN struct {
#if PPC_ABI == PPC_ABI_POWEROPEN
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
_isr, _entry_point ) \
_isr, _entry_point, _is_fp ) \
{ \
unsigned32 sp, *desc; \
\
@@ -816,11 +817,11 @@ EXTERN struct {
*
* RTEMS guarantees that (1) will never happen so it is not a concern.
* (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
* _CPU_Priority_Bits_index(). These three form a set of routines
* _CPU_Priority_bits_index(). These three form a set of routines
* which must logically operate together. Bits in the _value are
* set and cleared based on masks built by _CPU_Priority_mask().
* The basic major and minor values calculated by _Priority_Major()
* and _Priority_Minor() are "massaged" by _CPU_Priority_Bits_index()
* and _Priority_Minor() are "massaged" by _CPU_Priority_bits_index()
* to properly range between the values returned by the "find first bit"
* instruction. This makes it possible for _Priority_Get_highest() to
* calculate the major and directly index into the minor table.
@@ -855,6 +856,9 @@ EXTERN struct {
* bit set
*/
#define CPU_USE_GENERIC_BITFIELD_CODE FALSE
#define CPU_USE_GENERIC_BITFIELD_DATA FALSE
#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
{ \
asm volatile ("cntlzw %0, %1" : "=r" ((_output)), "=r" ((_value)) : \
@@ -879,7 +883,7 @@ EXTERN struct {
* for that routine.
*/
#define _CPU_Priority_Bits_index( _priority ) \
#define _CPU_Priority_bits_index( _priority ) \
(_priority)
/* end of Priority handler macros */
+118
View File
@@ -0,0 +1,118 @@
#
# $Id$
#
This file discusses SPARC specific issues which are important to
this port. The primary topics in this file are:
+ Global Register Usage
+ Stack Frame
+ EF bit in the PSR
Global Register Usage
=====================
This information on register usage is based heavily on a comment in the
file gcc-2.7.0/config/sparc/sparc.h in the the gcc 2.7.0 source.
+ g0 is hardwired to 0
+ On non-v9 systems:
- g1 is free to use as temporary.
- g2-g4 are reserved for applications. Gcc normally uses them as
temporaries, but this can be disabled via the -mno-app-regs option.
- g5 through g7 are reserved for the operating system.
+ On v9 systems:
- g1 and g5 are free to use as temporaries.
- g2-g4 are reserved for applications (the compiler will not normally use
them, but they can be used as temporaries with -mapp-regs).
- g6-g7 are reserved for the operating system.
NOTE: As of gcc 2.7.0 register g1 was used in the following scenarios:
+ as a temporary by the 64 bit sethi pattern
+ when restoring call-preserved registers in large stack frames
RTEMS places no constraints on the usage of the global registers. Although
gcc assumes that either g5-g7 (non-V9) or g6-g7 (V9) are reserved for the
operating system, RTEMS does not assume any special use for them.
Stack Frame
===========
The stack grows downward (i.e. to lower addresses) on the SPARC architecture.
The following is the organization of the stack frame:
| ............... |
fp | |
+-------------------------------+
| |
| Local registers, temporaries, |
| and saved floats | x bytes
| |
sp + x +-------------------------------+
| |
| outgoing parameters past |
| the sixth one | x bytes
| |
sp + 92 +-------------------------------+ *
| | *
| area for callee to save | *
| register arguments | * 24 bytes
| | *
sp + 68 +-------------------------------+ *
| | *
| structure return pointer | * 4 bytes
| | *
sp + 64 +-------------------------------+ *
| | *
| local register set | * 32 bytes
| | *
sp + 32 +-------------------------------+ *
| | *
| input register set | * 32 bytes
| | *
sp +-------------------------------+ *
* = minimal stack frame
x = optional components
EF bit in the PSR
=================
The EF (enable floating point unit) in the PSR is utilized in this port to
prevent non-floating point tasks from performing floating point
operations. This bit is maintained as part of the integer context.
However, the floating point context is switched BEFORE the integer
context. Thus the EF bit in place at the time of the FP switch may
indicate that FP operations are disabled. This occurs on certain task
switches, when the EF bit will be 0 for the outgoing task and thus a fault
will be generated on the first FP operation of the FP context save.
The remedy for this is to enable FP access as the first step in both the
save and restore of the FP context area. This bit will be subsequently
reloaded by the integer context switch.
Two of the scenarios which demonstrate this problem are outlined below:
1. When the first FP task is switched to. The system tasks are not FP and
thus would be unable to restore the FP context of the incoming task.
2. On a deferred FP context switch. In this case, the system might switch
from FP Task A to non-FP Task B and then to FP Task C. In this scenario,
the floating point state must technically be saved by a non-FP task.
+15 -1
View File
@@ -28,7 +28,9 @@
*/
#define ASM
#include <rtems/score/sparc.h>
#include <rtems/score/cpu.h>
/*
* Recent versions of GNU cpp define variables which indicate the
@@ -37,7 +39,9 @@
* have to define these as appropriate.
*/
/* XXX This does not appear to work on gcc 2.7.0 on the sparc */
/* 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. */
#undef __USER_LABEL_PREFIX__
#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__ _
@@ -91,6 +95,16 @@
#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
#endif
/* end of include file */
+282 -90
View File
@@ -7,52 +7,115 @@
#include <rtems/system.h>
#include <rtems/score/isr.h>
/* _CPU_Initialize
#if defined(erc32)
#include <erc32.h>
#endif
/*
* This initializes the set of opcodes placed in each 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.
*/
const CPU_Trap_table_entry _CPU_Trap_slot_template = {
0xa1480000, /* mov %psr, %l0 */
0x29000000, /* sethi %hi(_handler), %l4 */
0x81c52000, /* jmp %l4 + %lo(_handler) */
0xa6102000 /* mov _vector, %l3 */
};
/*PAGE
*
* _CPU_Initialize
*
* This routine performs processor dependent initialization.
*
* INPUT PARAMETERS:
* Input Parameters:
* cpu_table - CPU table to initialize
* thread_dispatch - address of disptaching routine
*
* Output Parameters: NONE
*
* NOTE: There is no need to save the pointer to the thread dispatch routine.
* The SPARC's assembly code can reference it directly with no problems.
*/
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
void (*thread_dispatch) /* ignored on this CPU */
)
{
void *pointer;
void *pointer;
unsigned32 trap_table_start;
unsigned32 tbr_value;
CPU_Trap_table_entry *old_tbr;
CPU_Trap_table_entry *trap_table;
/*
* The thread_dispatch argument is the address of the entry point
* for the routine called at the end of an ISR once it has been
* decided a context switch is necessary. On some compilation
* systems it is difficult to call a high-level language routine
* from assembly. This allows us to trick these systems.
*
* If you encounter this problem save the entry point in a CPU
* dependent variable.
* Install the executive's trap table. All entries from the original
* trap table are copied into the executive's trap table. This is essential
* since this preserves critical trap handlers such as the window underflow
* and overflow handlers. It is the responsibility of the BSP to provide
* install these in the initial trap table.
*/
trap_table_start = (unsigned32) &_CPU_Trap_Table_area;
if (trap_table_start & (SPARC_TRAP_TABLE_ALIGNMENT-1))
trap_table_start = (trap_table_start + SPARC_TRAP_TABLE_ALIGNMENT) &
~(SPARC_TRAP_TABLE_ALIGNMENT-1);
_CPU_Thread_dispatch_pointer = thread_dispatch;
trap_table = (CPU_Trap_table_entry *) trap_table_start;
sparc_get_tbr( tbr_value );
old_tbr = (CPU_Trap_table_entry *) (tbr_value & 0xfffff000);
memcpy( trap_table, (void *) old_tbr, 256 * sizeof( CPU_Trap_table_entry ) );
sparc_set_tbr( trap_table_start );
/*
* If there is not an easy way to initialize the FP context
* during Context_Initialize, then it is usually easier to
* save an "uninitialized" FP context here and copy it to
* the task's during Context_Initialize.
* This seems to be the most appropriate way to obtain an initial
* FP context on the SPARC. The NULL fp context is copied it to
* the task's FP context during Context_Initialize.
*/
pointer = &_CPU_Null_fp_context;
_CPU_Context_save_fp( &pointer );
/*
* Grab our own copy of the user's CPU table.
*/
_CPU_Table = *cpu_table;
#if defined(erc32)
/*
* ERC32 specific initialization
*/
_ERC32_MEC_Timer_Control_Mirror = 0;
ERC32_MEC.Timer_Control = 0;
ERC32_MEC.Control |= ERC32_CONFIGURATION_POWER_DOWN_ALLOWED;
#endif
}
/*PAGE
*
* _CPU_ISR_Get_level
*
* Input Parameters: NONE
*
* Output Parameters:
* returns the current interrupt level (PIL field of the PSR)
*/
unsigned32 _CPU_ISR_Get_level( void )
@@ -64,134 +127,263 @@ unsigned32 _CPU_ISR_Get_level( void )
return level;
}
/* _CPU_ISR_install_vector
/*PAGE
*
* _CPU_ISR_install_raw_handler
*
* This routine installs the specified handler as a "raw" non-executive
* supported trap handler (a.k.a. interrupt service routine).
*
* Input Parameters:
* vector - trap table entry number plus synchronous
* vs. asynchronous information
* new_handler - address of the handler to be installed
* old_handler - pointer to an address of the handler previously installed
*
* Output Parameters: NONE
* *new_handler - address of the handler previously installed
*
* NOTE:
*
* 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.
*/
void _CPU_ISR_install_raw_handler(
unsigned32 vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
unsigned32 real_vector;
CPU_Trap_table_entry *tbr;
CPU_Trap_table_entry *slot;
unsigned32 u32_tbr;
unsigned32 u32_handler;
/*
* Get the "real" trap number for this vector ignoring the synchronous
* versus asynchronous indicator included with our vector numbers.
*/
real_vector = SPARC_REAL_TRAP_NUMBER( vector );
/*
* Get the current base address of the trap table and calculate a pointer
* to the slot we are interested in.
*/
sparc_get_tbr( u32_tbr );
u32_tbr &= 0xfffff000;
tbr = (CPU_Trap_table_entry *) u32_tbr;
slot = &tbr[ real_vector ];
/*
* Get the address of the old_handler from the trap table.
*
* NOTE: The old_handler returned will be bogus if it does not follow
* the RTEMS model.
*/
#define HIGH_BITS_MASK 0xFFFFFC00
#define HIGH_BITS_SHIFT 10
#define LOW_BITS_MASK 0x000003FF
if ( slot->mov_psr_l0 == _CPU_Trap_slot_template.mov_psr_l0 ) {
u32_handler =
((slot->sethi_of_handler_to_l4 & HIGH_BITS_MASK) << HIGH_BITS_SHIFT) |
(slot->jmp_to_low_of_handler_plus_l4 & LOW_BITS_MASK);
*old_handler = (proc_ptr) u32_handler;
} else
*old_handler = 0;
/*
* Copy the template to the slot and then fix it.
*/
*slot = _CPU_Trap_slot_template;
u32_handler = (unsigned32) new_handler;
slot->mov_vector_l3 |= vector;
slot->sethi_of_handler_to_l4 |=
(u32_handler & HIGH_BITS_MASK) >> HIGH_BITS_SHIFT;
slot->jmp_to_low_of_handler_plus_l4 |= (u32_handler & LOW_BITS_MASK);
}
/*PAGE
*
* _CPU_ISR_install_vector
*
* This kernel routine installs the RTEMS handler for the
* specified vector.
*
* Input parameters:
* vector - interrupt vector number
* old_handler - former ISR for this vector number
* new_handler - replacement ISR for this vector number
* vector - interrupt vector number
* new_handler - replacement ISR for this vector number
* old_handler - pointer to former ISR for this vector number
*
* Output parameters: NONE
* Output parameters:
* *old_handler - former ISR for this vector number
*
*/
void _CPU_ISR_install_vector(
unsigned32 vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
*old_handler = _ISR_Vector_table[ vector ];
unsigned32 real_vector;
proc_ptr ignored;
/*
* Get the "real" trap number for this vector ignoring the synchronous
* versus asynchronous indicator included with our vector numbers.
*/
real_vector = SPARC_REAL_TRAP_NUMBER( vector );
/*
* If the interrupt vector table is a table of pointer to isr entry
* points, then we need to install the appropriate RTEMS interrupt
* handler for this vector number.
* Return the previous ISR handler.
*/
*old_handler = _ISR_Vector_table[ real_vector ];
/*
* Install the wrapper so this ISR can be invoked properly.
*/
_CPU_ISR_install_raw_handler( vector, _ISR_Handler, &ignored );
/*
* We put the actual user ISR address in '_ISR_vector_table'. This will
* be used by the _ISR_Handler so the user gets control.
*/
_ISR_Vector_table[ vector ] = new_handler;
}
/*PAGE
*
* _CPU_Install_interrupt_stack
*/
void _CPU_Install_interrupt_stack( void )
{
_ISR_Vector_table[ real_vector ] = new_handler;
}
/*PAGE
*
* _CPU_Context_Initialize
*
* This kernel routine initializes the basic non-FP context area associated
* with each thread.
*
* Input parameters:
* the_context - pointer to the context area
* stack_base - address of memory for the SPARC
* size - size in bytes of the stack area
* new_level - interrupt level for this context area
* entry_point - the starting execution point for this this context
* is_fp - TRUE if this context is associated with an FP thread
*
* Output parameters: NONE
*/
/*
* The following constants assist in building a thread's initial context.
*/
#define CPU_FRAME_SIZE (112) /* based on disassembled test code */
#define ADDR_ADJ_OFFSET -8
void _CPU_Context_Initialize(
Context_Control *_the_context,
unsigned32 *_stack_base,
unsigned32 _size,
unsigned32 _new_level,
void *_entry_point
Context_Control *the_context,
unsigned32 *stack_base,
unsigned32 size,
unsigned32 new_level,
void *entry_point,
boolean is_fp
)
{
unsigned32 jmp_addr;
unsigned32 _stack_high; /* highest "stack aligned" address */
unsigned32 _the_size;
unsigned32 stack_high; /* highest "stack aligned" address */
unsigned32 the_size;
unsigned32 tmp_psr;
jmp_addr = (unsigned32) _entry_point;
/*
* On CPUs with stacks which grow down (i.e. SPARC), we build the stack
* based on the _stack_high address.
* based on the stack_high address.
*/
_stack_high = ((unsigned32)(_stack_base) + _size);
_stack_high &= ~(CPU_STACK_ALIGNMENT - 1);
stack_high = ((unsigned32)(stack_base) + size);
stack_high &= ~(CPU_STACK_ALIGNMENT - 1);
_the_size = _size & ~(CPU_STACK_ALIGNMENT - 1);
the_size = size & ~(CPU_STACK_ALIGNMENT - 1);
/* XXX following code is based on unix port */
/*
* XXX SPARC port needs a diagram like this one...
* See /usr/include/sys/stack.h in Solaris 2.3 for a nice
* diagram of the stack.
* See the README in this directory for a diagram of the stack.
*/
_the_context->o7 = jmp_addr + ADDR_ADJ_OFFSET;
_the_context->o6 = (unsigned32)(_stack_high - CPU_FRAME_SIZE);
_the_context->i6 = (unsigned32)(_stack_high);
#if 0
_the_context->rp = jmp_addr + ADDR_ADJ_OFFSET;
_the_context->sp = (unsigned32)(_stack_high - CPU_FRAME_SIZE);
_the_context->fp = (unsigned32)(_stack_high);
#endif
the_context->o7 = ((unsigned32) entry_point) - 8;
the_context->o6_sp = stack_high - CPU_MINIMUM_STACK_FRAME_SIZE;
the_context->i6_fp = stack_high;
_the_context->wim = 0x01;
/*
* Build the PSR for the task. Most everything can be 0 and the
* CWP is corrected during the context switch.
*
* The EF bit determines if the floating point unit is available.
* The FPU is ONLY enabled if the context is associated with an FP task
* and this SPARC model has an FPU.
*/
sparc_get_psr( tmp_psr );
tmp_psr &= ~SPARC_PIL_MASK;
tmp_psr |= (((_new_level) << 8) & SPARC_PIL_MASK);
tmp_psr = (tmp_psr & ~0x07) | 0x07; /* XXX should use num windows */
_the_context->psr = tmp_psr;
tmp_psr &= ~SPARC_PSR_PIL_MASK;
tmp_psr |= (new_level << 8) & SPARC_PSR_PIL_MASK;
tmp_psr &= ~SPARC_PSR_EF_MASK; /* disabled by default */
#if (SPARC_HAS_FPU == 1)
/*
* If this bit is not set, then a task gets a fault when it accesses
* a floating point register. This is a nice way to detect floating
* point tasks which are not currently declared as such.
*/
if ( is_fp )
tmp_psr |= SPARC_PSR_EF_MASK;
#endif
the_context->psr = tmp_psr;
}
/*PAGE
*
* _CPU_Internal_threads_Idle_thread_body
*
* NOTES:
*
* 1. This is the same as the regular CPU independent algorithm.
*
* 2. If you implement this using a "halt", "idle", or "shutdown"
* instruction, then don't forget to put it in an infinite loop.
*
* 3. Be warned. Some processors with onboard DMA have been known
* to stop the DMA if the CPU were put in IDLE mode. This might
* also be a problem with other on-chip peripherals. So use this
* hook with caution.
* Some SPARC implementations have low power, sleep, or idle modes. This
* tries to take advantage of those models.
*/
#if (CPU_PROVIDES_IDLE_THREAD_BODY == TRUE)
/*
* This is the implementation for the erc32.
*
* NOTE: Low power mode was enabled at initialization time.
*/
#if defined(erc32)
void _CPU_Internal_threads_Idle_thread_body( void )
{
for( ; ; )
/* insert your "halt" instruction here */ ;
while (1) {
ERC32_MEC.Power_Down = 0; /* value is irrelevant */
}
}
#endif
#endif /* CPU_PROVIDES_IDLE_THREAD_BODY */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+13 -3
View File
@@ -22,12 +22,22 @@
* is used to look up the directive.
*
* void RTEMS()
* {
* }
*/
.align 4
PUBLIC(RTEMS)
SYM(RTEMS):
ret
/*
* g2 was chosen because gcc uses it as a scratch register in
* similar code scenarios and the other locals, ins, and outs
* are off limits to this routine unless it does a "save" and
* copies its in registers to the outs which only works up until
* 6 parameters. Best to take the simple approach in this case.
*/
sethi SYM(_Entry_points), %g2
or %g2, %lo(SYM(_Entry_points)), %g2
sll %g1, 2, %g1
add %g1, %g2, %g2
jmp %g2
nop
+117 -33
View File
@@ -1,7 +1,7 @@
/* sparc.h
*
* This include file contains information pertaining to the Motorola
* SPARC processor family.
* This include file contains information pertaining to the SPARC
* processor family.
*
* $Id$
*/
@@ -37,8 +37,7 @@ extern "C" {
/*
* This file contains the information required to build
* RTEMS for a particular member of the "sparc"
* family when executing in protected mode. It does
* 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.
@@ -51,15 +50,25 @@ extern "C" {
*
* + SPARC_HAS_BITSCAN
* 0 - does not have scan instructions
* 1 - has scan instruction (no support implemented)
* 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.
*
* + SPARC_HAS_LOW_POWER_MODE
* 0 - does not have low power mode support (or not supported)
* 1 - has low power mode and thus a CPU model dependent idle task.
*
*/
#if defined(erc32)
#define CPU_MODEL_NAME "erc32"
#define SPARC_HAS_FPU 1
#define SPARC_HAS_BITSCAN 0
#define CPU_MODEL_NAME "erc32"
#define SPARC_HAS_FPU 1
#define SPARC_HAS_BITSCAN 0
#define SPARC_NUMBER_OF_REGISTER_WINDOWS 8
#define SPARC_HAS_LOW_POWER_MODE 1
#else
@@ -73,6 +82,49 @@ extern "C" {
#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
#define SPARC_PSR_ET_MASK 0x00000020 /* bit 5 */
#define SPARC_PSR_PS_MASK 0x00000040 /* bit 6 */
#define SPARC_PSR_S_MASK 0x00000080 /* bit 7 */
#define SPARC_PSR_PIL_MASK 0x00000F00 /* bits 8 - 11 */
#define SPARC_PSR_EF_MASK 0x00001000 /* bit 12 */
#define SPARC_PSR_EC_MASK 0x00002000 /* bit 13 */
#define SPARC_PSR_ICC_MASK 0x00F00000 /* bits 20 - 23 */
#define SPARC_PSR_VER_MASK 0x0F000000 /* bits 24 - 27 */
#define SPARC_PSR_IMPL_MASK 0xF0000000 /* bits 28 - 31 */
#define SPARC_PSR_CWP_BIT_POSITION 0 /* bits 0 - 4 */
#define SPARC_PSR_ET_BIT_POSITION 5 /* bit 5 */
#define SPARC_PSR_PS_BIT_POSITION 6 /* bit 6 */
#define SPARC_PSR_S_BIT_POSITION 7 /* bit 7 */
#define SPARC_PSR_PIL_BIT_POSITION 8 /* bits 8 - 11 */
#define SPARC_PSR_EF_BIT_POSITION 12 /* bit 12 */
#define SPARC_PSR_EC_BIT_POSITION 13 /* bit 13 */
#define SPARC_PSR_ICC_BIT_POSITION 20 /* bits 20 - 23 */
#define SPARC_PSR_VER_BIT_POSITION 24 /* bits 24 - 27 */
#define SPARC_PSR_IMPL_BIT_POSITION 28 /* bits 28 - 31 */
#ifndef ASM
/*
* Standard nop
*/
@@ -83,7 +135,7 @@ extern "C" {
} while ( 0 )
/*
* Some macros to aid in accessing special registers.
* Get and set the PSR
*/
#define sparc_get_psr( _psr ) \
@@ -94,26 +146,56 @@ extern "C" {
#define sparc_set_psr( _psr ) \
do { \
asm volatile ( "wr %%g0,%0,%%psr " : "=r" ((_psr)) : "0" ((_psr)) ); \
nop(); nop(); nop(); \
asm volatile ( "mov %0, %%psr " : "=r" ((_psr)) : "0" ((_psr)) ); \
nop(); \
nop(); \
nop(); \
} while ( 0 )
/*
* Get and set the TBR
*/
#define sparc_get_tbr( _tbr ) \
do { \
(_tbr) = 0; /* to avoid unitialized warnings */ \
asm volatile( "rd %%tbr, %0" : "=r" (_tbr) : "0" (_tbr) ); \
} while ( 0 )
#define sparc_set_tbr( _tbr ) \
do { \
asm volatile( "wr %0, 0, %%tbr" : "=r" (_tbr) : "0" (_tbr) ); \
} while ( 0 )
/*
* Get and set the WIM
*/
#define sparc_get_wim( _wim ) \
do { \
asm volatile( "rd %%wim, %0" : "=r" (_wim) : "0" (_wim) ); \
asm volatile( "rd %%wim, %0" : "=r" (_wim) : "0" (_wim) ); \
} while ( 0 )
#define sparc_set_wim( _wim ) \
do { \
asm volatile( "wr %0, %%wim" : "=r" (_wim) : "0" (_wim) ); \
nop(); \
nop(); \
nop(); \
} while ( 0 )
/*
* Get and set the Y
*/
#define sparc_get_y( _y ) \
do { \
asm volatile( "rd %%y, %0" : "=r" (_y) : "0" (_y) ); \
} while ( 0 )
#define sparc_set_y( _y ) \
do { \
asm volatile( "wr %0, %%y" : "=r" (_y) : "0" (_y) ); \
} while ( 0 )
/*
@@ -121,42 +203,41 @@ extern "C" {
*
*/
#define SPARC_PIL_MASK 0x00000F00
#define sparc_disable_interrupts( _level ) \
do { register unsigned int _mask = SPARC_PIL_MASK; \
(_level) = 0; \
do { \
register unsigned int _newlevel; \
\
asm volatile ( "rd %%psr,%0 ; \
wr %0,%1,%%psr " \
: "=r" ((_level)), "=r" (_mask) \
: "0" ((_level)), "1" (_mask) \
); \
nop(); nop(); nop(); \
sparc_get_psr( _level ); \
(_newlevel) = (_level) | SPARC_PSR_PIL_MASK; \
sparc_set_psr( _newlevel ); \
} while ( 0 )
#define sparc_enable_interrupts( _level ) \
do { unsigned int _tmp; \
do { \
unsigned int _tmp; \
\
sparc_get_psr( _tmp ); \
_tmp &= ~SPARC_PIL_MASK; \
_tmp |= (_level) & SPARC_PIL_MASK; \
_tmp &= ~SPARC_PSR_PIL_MASK; \
_tmp |= (_level) & SPARC_PSR_PIL_MASK; \
sparc_set_psr( _tmp ); \
} while ( 0 )
#define sparc_flash_interrupts( _level ) \
do { \
register unsigned32 _ignored = 0; \
sparc_enable_interrupts( (_level) ); \
sparc_disable_interrupts( _ignored ); \
register unsigned32 _ignored = 0; \
\
sparc_enable_interrupts( (_level) ); \
sparc_disable_interrupts( _ignored ); \
} while ( 0 )
#define sparc_set_interrupt_level( _new_level ) \
do { register unsigned32 _new_psr_level = 0; \
do { \
register unsigned32 _new_psr_level = 0; \
\
sparc_get_psr( _new_psr_level ); \
_new_psr_level &= ~SPARC_PIL_MASK; \
_new_psr_level |= (((_new_level) << 8) & SPARC_PIL_MASK); \
_new_psr_level &= ~SPARC_PSR_PIL_MASK; \
_new_psr_level |= \
(((_new_level) << SPARC_PSR_PIL_BIT_POSITION) & SPARC_PSR_PIL_MASK); \
sparc_set_psr( _new_psr_level ); \
} while ( 0 )
@@ -165,9 +246,12 @@ extern "C" {
register unsigned32 _psr_level = 0; \
\
sparc_get_psr( _psr_level ); \
(_level) = (_psr_level & SPARC_PIL_MASK) >> 8; \
(_level) = \
(_psr_level & SPARC_PSR_PIL_MASK) >> SPARC_PSR_PIL_BIT_POSITION; \
} while ( 0 )
#endif
#ifdef __cplusplus
}
#endif
+13 -13
View File
@@ -1,6 +1,6 @@
/* sparctypes.h
*
* This include file contains type definitions pertaining to the Intel
* This include file contains type definitions pertaining to the
* SPARC processor family.
*
* $Id$
@@ -19,22 +19,22 @@ extern "C" {
* This section defines the basic types for this processor.
*/
typedef unsigned char unsigned8; /* unsigned 8-bit integer */
typedef unsigned short unsigned16; /* unsigned 16-bit integer */
typedef unsigned int unsigned32; /* unsigned 32-bit integer */
typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
typedef unsigned char unsigned8; /* unsigned 8-bit integer */
typedef unsigned short unsigned16; /* unsigned 16-bit integer */
typedef unsigned int unsigned32; /* unsigned 32-bit integer */
typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
typedef unsigned16 Priority_Bit_map_control;
typedef unsigned16 Priority_Bit_map_control;
typedef signed char signed8; /* 8-bit signed integer */
typedef signed short signed16; /* 16-bit signed integer */
typedef signed int signed32; /* 32-bit signed integer */
typedef signed long long signed64; /* 64 bit signed integer */
typedef signed char signed8; /* 8-bit signed integer */
typedef signed short signed16; /* 16-bit signed integer */
typedef signed int signed32; /* 32-bit signed integer */
typedef signed long long signed64; /* 64 bit signed integer */
typedef unsigned32 boolean; /* Boolean value */
typedef unsigned32 boolean; /* Boolean value */
typedef float single_precision; /* single precision float */
typedef double double_precision; /* double precision float */
typedef float single_precision; /* single precision float */
typedef double double_precision; /* double precision float */
typedef void sparc_isr;
typedef void ( *sparc_isr_entry )( void );
+6 -46
View File
@@ -341,17 +341,10 @@ void _CPU_Install_interrupt_stack( void )
*
* _CPU_Internal_threads_Idle_thread_body
*
* NOTES:
*
* 1. This is the same as the regular CPU independent algorithm.
*
* 2. If you implement this using a "halt", "idle", or "shutdown"
* instruction, then don't forget to put it in an infinite loop.
*
* 3. Be warned. Some processors with onboard DMA have been known
* to stop the DMA if the CPU were put in IDLE mode. This might
* also be a problem with other on-chip peripherals. So use this
* hook with caution.
* Stop until we get a signal which is the logically the same thing
* entering low-power or sleep mode on a real processor and waiting for
* an interrupt. This significantly reduces the consumption of host
* CPU cycles which is again similar to low power mode.
*/
void _CPU_Internal_threads_Idle_thread_body( void )
@@ -370,7 +363,8 @@ void _CPU_Context_Initialize(
unsigned32 *_stack_base,
unsigned32 _size,
unsigned32 _new_level,
void *_entry_point
void *_entry_point,
boolean _is_fp
)
{
void *source;
@@ -697,49 +691,15 @@ void _CPU_Fatal_error(unsigned32 error)
_exit(error);
}
/*PAGE
*
* _CPU_ffs
*/
int _CPU_ffs(unsigned32 value)
{
int output;
extern int ffs( int );
output = ffs(value);
output = output - 1;
return output;
}
/*
* Special Purpose Routines to hide the use of UNIX system calls.
*/
#if 0
/* XXX clock had this set of #define's */
/*
* In order to get the types and prototypes used in this file under
* Solaris 2.3, it is necessary to pull the following magic.
*/
#if defined(solaris)
#warning "Ignore the undefining __STDC__ warning"
#undef __STDC__
#define __STDC__ 0
#undef _POSIX_C_SOURCE
#endif
#endif
int _CPU_Get_clock_vector( void )
{
return SIGALRM;
}
void _CPU_Start_clock(
int microseconds
)
+22 -29
View File
@@ -549,7 +549,8 @@ EXTERN void (*_CPU_Thread_dispatch_pointer)();
* by RTEMS.
*/
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 64
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 64
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
/*
* Should be large enough to run all RTEMS tests. This insures
@@ -721,7 +722,8 @@ extern void _CPU_Context_Initialize(
unsigned32 *_stack_base,
unsigned32 _size,
unsigned32 _new_level,
void *_entry_point
void *_entry_point,
boolean _is_fp
);
/* end of Context handler macros */
@@ -757,11 +759,11 @@ extern void _CPU_Context_Initialize(
*
* RTEMS guarantees that (1) will never happen so it is not a concern.
* (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
* _CPU_Priority_Bits_index(). These three form a set of routines
* _CPU_Priority_bits_index(). These three form a set of routines
* which must logically operate together. Bits in the _value are
* set and cleared based on masks built by _CPU_Priority_mask().
* The basic major and minor values calculated by _Priority_Major()
* and _Priority_Minor() are "massaged" by _CPU_Priority_Bits_index()
* and _Priority_Minor() are "massaged" by _CPU_Priority_bits_index()
* to properly range between the values returned by the "find first bit"
* instruction. This makes it possible for _Priority_Get_highest() to
* calculate the major and directly index into the minor table.
@@ -796,30 +798,25 @@ extern void _CPU_Context_Initialize(
* bit set
*/
#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
_output = _CPU_ffs( _value )
/*
* The UNIX port uses the generic C algorithm for bitfield scan to avoid
* dependencies on either a native bitscan instruction or an ffs() in the
* C library.
*/
#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
/* end of Bitfield handler macros */
/* Priority handler handler macros */
/*
* This routine builds the mask which corresponds to the bit fields
* as searched by _CPU_Bitfield_Find_first_bit(). See the discussion
* for that routine.
* The UNIX port uses the generic C algorithm for bitfield scan to avoid
* dependencies on either a native bitscan instruction or an ffs() in the
* C library.
*/
#define _CPU_Priority_Mask( _bit_number ) \
( 1 << (_bit_number) )
/*
* This routine translates the bit numbers returned by
* _CPU_Bitfield_Find_first_bit() into something suitable for use as
* a major or minor component of a priority. See the discussion
* for that routine.
*/
#define _CPU_Priority_Bits_index( _priority ) \
(_priority)
/* end of Priority handler macros */
/* functions */
@@ -935,10 +932,6 @@ void _CPU_Fatal_error(
unsigned32 _error
);
int _CPU_ffs(
unsigned32 _value
);
/* The following routine swaps the endian format of an unsigned int.
* It must be static because it is referenced indirectly.
*
+49
View File
@@ -38,9 +38,58 @@ extern "C" {
* significant impact on the performance of the executive as a whole.
*/
#if ( CPU_USE_GENERIC_BITFIELD_DATA == TRUE )
#ifndef INIT
extern const unsigned char __log2table[256];
#else
const unsigned char __log2table[256] = {
7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#endif
#endif
#if ( CPU_USE_GENERIC_BITFIELD_CODE == FALSE )
#define _Bitfield_Find_first_bit( _value, _bit_number ) \
_CPU_Bitfield_Find_first_bit( _value, _bit_number )
#else
/*
* The following must be a macro because if a CPU specific version
* is used it will most likely use inline assembly.
*/
#define _Bitfield_Find_first_bit( _value, _bit_number ) \
{ \
register __value = (_value); \
register const unsigned char *__p = __log2table; \
\
if ( __value < 0x100 ) \
(_bit_number) = __p[ __value ] + 8; \
else \
(_bit_number) = __p[ __value >> 8 ]; \
}
#endif
#ifdef __cplusplus
}
#endif
+3 -2
View File
@@ -47,8 +47,9 @@ EXTERN boolean _Context_Switch_necessary;
* thread's initial state.
*/
#define _Context_Initialize( _the_context, _stack, _size, _isr, _entry ) \
_CPU_Context_Initialize( _the_context, _stack, _size, _isr, _entry )
#define \
_Context_Initialize( _the_context, _stack, _size, _isr, _entry, _is_fp ) \
_CPU_Context_Initialize( _the_context, _stack, _size, _isr, _entry, _is_fp )
/*
* _Context_Switch
+11 -4
View File
@@ -50,11 +50,18 @@ typedef ISR_Handler ( *ISR_Handler_entry )(
ISR_Vector_number
);
/*
* This constant promotes out the number of vectors supported by
* the current CPU being used.
* This constant promotes out the number of vectors truly supported by
* the current CPU being used. This is usually the number of distinct vectors
* the cpu can vector.
*/
#define ISR_NUMBER_OF_VECTORS CPU_INTERRUPT_NUMBER_OF_VECTORS
#define ISR_NUMBER_OF_VECTORS CPU_INTERRUPT_NUMBER_OF_VECTORS
/*
* This constant promotes out the highest valid interrupt vector number.
*/
#define ISR_INTERRUPT_MAXIMUM_VECTOR_NUMBER CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER
/*
* The following is TRUE if signals have been sent to the currently
@@ -75,7 +82,7 @@ EXTERN unsigned32 _ISR_Nest_level;
* interrupt service routines are vectored by the ISR Handler via this table.
*/
EXTERN ISR_Handler_entry _ISR_Vector_table[CPU_INTERRUPT_NUMBER_OF_VECTORS];
EXTERN ISR_Handler_entry _ISR_Vector_table[ ISR_NUMBER_OF_VECTORS ];
/*
* _ISR_Handler_initialization
+45
View File
@@ -113,6 +113,51 @@ STATIC INLINE unsigned32 _Priority_Minor (
Priority_Control the_priority
);
/*
* _Priority_Mask
*
* DESCRIPTION:
*
* This function returns the mask associated with the major or minor
* number passed to it.
*/
#if ( CPU_USE_GENERIC_BITFIELD_CODE == TRUE )
STATIC INLINE unsigned32 _Priority_Mask (
unsigned32 bit_number
);
#else
#define _Priority_Mask( _bit_number ) \
_CPU_Priority_Mask( _bit_number )
#endif
/*
* _Priority_Bits_index
*
* DESCRIPTION:
*
* This function translates the bit numbers returned by the bit scan
* of a priority bit field into something suitable for use as
* a major or minor component of a priority.
*/
#if ( CPU_USE_GENERIC_BITFIELD_CODE == TRUE )
STATIC INLINE unsigned32 _Priority_Bits_index (
unsigned32 bit_number
);
#else
#define _Priority_Bits_index( _priority ) \
_CPU_Priority_bits_index( _priority )
#endif
/*
* _Priority_Add_to_bit_map
*
@@ -38,9 +38,58 @@ extern "C" {
* significant impact on the performance of the executive as a whole.
*/
#if ( CPU_USE_GENERIC_BITFIELD_DATA == TRUE )
#ifndef INIT
extern const unsigned char __log2table[256];
#else
const unsigned char __log2table[256] = {
7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#endif
#endif
#if ( CPU_USE_GENERIC_BITFIELD_CODE == FALSE )
#define _Bitfield_Find_first_bit( _value, _bit_number ) \
_CPU_Bitfield_Find_first_bit( _value, _bit_number )
#else
/*
* The following must be a macro because if a CPU specific version
* is used it will most likely use inline assembly.
*/
#define _Bitfield_Find_first_bit( _value, _bit_number ) \
{ \
register __value = (_value); \
register const unsigned char *__p = __log2table; \
\
if ( __value < 0x100 ) \
(_bit_number) = __p[ __value ] + 8; \
else \
(_bit_number) = __p[ __value >> 8 ]; \
}
#endif
#ifdef __cplusplus
}
#endif
@@ -47,8 +47,9 @@ EXTERN boolean _Context_Switch_necessary;
* thread's initial state.
*/
#define _Context_Initialize( _the_context, _stack, _size, _isr, _entry ) \
_CPU_Context_Initialize( _the_context, _stack, _size, _isr, _entry )
#define \
_Context_Initialize( _the_context, _stack, _size, _isr, _entry, _is_fp ) \
_CPU_Context_Initialize( _the_context, _stack, _size, _isr, _entry, _is_fp )
/*
* _Context_Switch
+11 -4
View File
@@ -50,11 +50,18 @@ typedef ISR_Handler ( *ISR_Handler_entry )(
ISR_Vector_number
);
/*
* This constant promotes out the number of vectors supported by
* the current CPU being used.
* This constant promotes out the number of vectors truly supported by
* the current CPU being used. This is usually the number of distinct vectors
* the cpu can vector.
*/
#define ISR_NUMBER_OF_VECTORS CPU_INTERRUPT_NUMBER_OF_VECTORS
#define ISR_NUMBER_OF_VECTORS CPU_INTERRUPT_NUMBER_OF_VECTORS
/*
* This constant promotes out the highest valid interrupt vector number.
*/
#define ISR_INTERRUPT_MAXIMUM_VECTOR_NUMBER CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER
/*
* The following is TRUE if signals have been sent to the currently
@@ -75,7 +82,7 @@ EXTERN unsigned32 _ISR_Nest_level;
* interrupt service routines are vectored by the ISR Handler via this table.
*/
EXTERN ISR_Handler_entry _ISR_Vector_table[CPU_INTERRUPT_NUMBER_OF_VECTORS];
EXTERN ISR_Handler_entry _ISR_Vector_table[ ISR_NUMBER_OF_VECTORS ];
/*
* _ISR_Handler_initialization
@@ -113,6 +113,51 @@ STATIC INLINE unsigned32 _Priority_Minor (
Priority_Control the_priority
);
/*
* _Priority_Mask
*
* DESCRIPTION:
*
* This function returns the mask associated with the major or minor
* number passed to it.
*/
#if ( CPU_USE_GENERIC_BITFIELD_CODE == TRUE )
STATIC INLINE unsigned32 _Priority_Mask (
unsigned32 bit_number
);
#else
#define _Priority_Mask( _bit_number ) \
_CPU_Priority_Mask( _bit_number )
#endif
/*
* _Priority_Bits_index
*
* DESCRIPTION:
*
* This function translates the bit numbers returned by the bit scan
* of a priority bit field into something suitable for use as
* a major or minor component of a priority.
*/
#if ( CPU_USE_GENERIC_BITFIELD_CODE == TRUE )
STATIC INLINE unsigned32 _Priority_Bits_index (
unsigned32 bit_number
);
#else
#define _Priority_Bits_index( _priority ) \
_CPU_Priority_bits_index( _priority )
#endif
/*
* _Priority_Add_to_bit_map
*
+1 -1
View File
@@ -38,7 +38,7 @@ STATIC INLINE boolean _ISR_Is_vector_number_valid (
unsigned32 vector
)
{
return ( vector < CPU_INTERRUPT_NUMBER_OF_VECTORS );
return ( vector <= CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER );
}
/*PAGE
+36 -5
View File
@@ -78,6 +78,37 @@ STATIC INLINE unsigned32 _Priority_Minor (
return ( the_priority % 16 );
}
#if ( CPU_USE_GENERIC_BITFIELD_CODE == TRUE )
/*PAGE
*
* _Priority_Mask
*
*/
STATIC INLINE unsigned32 _Priority_Mask (
unsigned32 bit_number
)
{
return (0x8000 >> bit_number);
}
/*PAGE
*
* _Priority_Bits_index
*
*/
STATIC INLINE unsigned32 _Priority_Bits_index (
unsigned32 bit_number
)
{
return bit_number;
}
#endif
/*PAGE
*
* _Priority_Add_to_bit_map
@@ -121,8 +152,8 @@ STATIC INLINE Priority_Control _Priority_Get_highest( void )
_Bitfield_Find_first_bit( _Priority_Major_bit_map, major );
_Bitfield_Find_first_bit( _Priority_Bit_map[major], minor );
return (_CPU_Priority_Bits_index( major ) << 4) +
_CPU_Priority_Bits_index( minor );
return (_Priority_Bits_index( major ) << 4) +
_Priority_Bits_index( minor );
}
/*PAGE
@@ -144,13 +175,13 @@ STATIC INLINE void _Priority_Initialize_information(
minor = _Priority_Minor( new_priority );
the_priority_map->minor =
&_Priority_Bit_map[ _CPU_Priority_Bits_index(major) ];
&_Priority_Bit_map[ _Priority_Bits_index(major) ];
mask = _CPU_Priority_Mask( major );
mask = _Priority_Mask( major );
the_priority_map->ready_major = mask;
the_priority_map->block_major = ~mask;
mask = _CPU_Priority_Mask( minor );
mask = _Priority_Mask( minor );
the_priority_map->ready_minor = mask;
the_priority_map->block_minor = ~mask;
}
+1 -1
View File
@@ -38,7 +38,7 @@ STATIC INLINE boolean _ISR_Is_vector_number_valid (
unsigned32 vector
)
{
return ( vector < CPU_INTERRUPT_NUMBER_OF_VECTORS );
return ( vector <= CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER );
}
/*PAGE
@@ -78,6 +78,37 @@ STATIC INLINE unsigned32 _Priority_Minor (
return ( the_priority % 16 );
}
#if ( CPU_USE_GENERIC_BITFIELD_CODE == TRUE )
/*PAGE
*
* _Priority_Mask
*
*/
STATIC INLINE unsigned32 _Priority_Mask (
unsigned32 bit_number
)
{
return (0x8000 >> bit_number);
}
/*PAGE
*
* _Priority_Bits_index
*
*/
STATIC INLINE unsigned32 _Priority_Bits_index (
unsigned32 bit_number
)
{
return bit_number;
}
#endif
/*PAGE
*
* _Priority_Add_to_bit_map
@@ -121,8 +152,8 @@ STATIC INLINE Priority_Control _Priority_Get_highest( void )
_Bitfield_Find_first_bit( _Priority_Major_bit_map, major );
_Bitfield_Find_first_bit( _Priority_Bit_map[major], minor );
return (_CPU_Priority_Bits_index( major ) << 4) +
_CPU_Priority_Bits_index( minor );
return (_Priority_Bits_index( major ) << 4) +
_Priority_Bits_index( minor );
}
/*PAGE
@@ -144,13 +175,13 @@ STATIC INLINE void _Priority_Initialize_information(
minor = _Priority_Minor( new_priority );
the_priority_map->minor =
&_Priority_Bit_map[ _CPU_Priority_Bits_index(major) ];
&_Priority_Bit_map[ _Priority_Bits_index(major) ];
mask = _CPU_Priority_Mask( major );
mask = _Priority_Mask( major );
the_priority_map->ready_major = mask;
the_priority_map->block_major = ~mask;
mask = _CPU_Priority_Mask( minor );
mask = _Priority_Mask( minor );
the_priority_map->ready_minor = mask;
the_priority_map->block_minor = ~mask;
}
+1 -1
View File
@@ -33,7 +33,7 @@
*/
#define _ISR_Is_vector_number_valid( _vector ) \
( (_vector) < CPU_INTERRUPT_NUMBER_OF_VECTORS )
( (_vector) <= CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER )
/*PAGE
*
+27 -5
View File
@@ -64,6 +64,28 @@
#define _Priority_Minor( _the_priority ) ( (_the_priority) % 16 )
#if ( CPU_USE_GENERIC_BITFIELD_CODE == TRUE )
/*PAGE
*
* _Priority_Mask
*
*/
#define _Priority_Mask( _bit_number ) \
(0x8000 >> _bit_number)
/*PAGE
*
* _Priority_Bits_index
*
*/
#define _Priority_Bits_index( _bit_number ) \
(_bit_number)
#endif
/*PAGE
*
* _Priority_Add_to_bit_map
@@ -103,8 +125,8 @@
_Bitfield_Find_first_bit( _Priority_Major_bit_map, major ); \
_Bitfield_Find_first_bit( _Priority_Bit_map[major], minor ); \
\
(_high_priority) = (_CPU_Priority_Bits_index( major ) * 16) + \
_CPU_Priority_Bits_index( minor ); \
(_high_priority) = (_Priority_Bits_index( major ) * 16) + \
_Priority_Bits_index( minor ); \
}
/*PAGE
@@ -124,13 +146,13 @@
_minor = _Priority_Minor( (_new_priority) ); \
\
(_the_priority_map)->minor = \
&_Priority_Bit_map[ _CPU_Priority_Bits_index(_major) ]; \
&_Priority_Bit_map[ _Priority_Bits_index(_major) ]; \
\
_mask = _CPU_Priority_Mask( _major ); \
_mask = _Priority_Mask( _major ); \
(_the_priority_map)->ready_major = _mask; \
(_the_priority_map)->block_major = ~_mask; \
\
_mask = _CPU_Priority_Mask( _minor ); \
_mask = _Priority_Mask( _minor ); \
(_the_priority_map)->ready_minor = _mask; \
(_the_priority_map)->block_minor = ~_mask; \
}
+1 -1
View File
@@ -33,7 +33,7 @@
*/
#define _ISR_Is_vector_number_valid( _vector ) \
( (_vector) < CPU_INTERRUPT_NUMBER_OF_VECTORS )
( (_vector) <= CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER )
/*PAGE
*
@@ -64,6 +64,28 @@
#define _Priority_Minor( _the_priority ) ( (_the_priority) % 16 )
#if ( CPU_USE_GENERIC_BITFIELD_CODE == TRUE )
/*PAGE
*
* _Priority_Mask
*
*/
#define _Priority_Mask( _bit_number ) \
(0x8000 >> _bit_number)
/*PAGE
*
* _Priority_Bits_index
*
*/
#define _Priority_Bits_index( _bit_number ) \
(_bit_number)
#endif
/*PAGE
*
* _Priority_Add_to_bit_map
@@ -103,8 +125,8 @@
_Bitfield_Find_first_bit( _Priority_Major_bit_map, major ); \
_Bitfield_Find_first_bit( _Priority_Bit_map[major], minor ); \
\
(_high_priority) = (_CPU_Priority_Bits_index( major ) * 16) + \
_CPU_Priority_Bits_index( minor ); \
(_high_priority) = (_Priority_Bits_index( major ) * 16) + \
_Priority_Bits_index( minor ); \
}
/*PAGE
@@ -124,13 +146,13 @@
_minor = _Priority_Minor( (_new_priority) ); \
\
(_the_priority_map)->minor = \
&_Priority_Bit_map[ _CPU_Priority_Bits_index(_major) ]; \
&_Priority_Bit_map[ _Priority_Bits_index(_major) ]; \
\
_mask = _CPU_Priority_Mask( _major ); \
_mask = _Priority_Mask( _major ); \
(_the_priority_map)->ready_major = _mask; \
(_the_priority_map)->block_major = ~_mask; \
\
_mask = _CPU_Priority_Mask( _minor ); \
_mask = _Priority_Mask( _minor ); \
(_the_priority_map)->ready_minor = _mask; \
(_the_priority_map)->block_minor = ~_mask; \
}
+5 -1
View File
@@ -805,9 +805,12 @@ void _Thread_Load_environment(
Thread_Control *the_thread
)
{
boolean is_fp = FALSE;
if ( the_thread->Start.fp_context ) {
the_thread->fp_context = the_thread->Start.fp_context;
_Context_Initialize_fp( &the_thread->fp_context );
is_fp = TRUE;
}
the_thread->is_preemptible = the_thread->Start.is_preemptible;
@@ -818,7 +821,8 @@ void _Thread_Load_environment(
the_thread->Start.Initial_stack.area,
the_thread->Start.Initial_stack.size,
the_thread->Start.isr_level,
_Thread_Handler
_Thread_Handler,
is_fp
);
}
+18 -7
View File
@@ -10,13 +10,13 @@
#define __RINGBUF_H__
#ifndef RINGBUF_QUEUE_LENGTH
#define RINGBUF_QUEUE_LENGTH 200
#define RINGBUF_QUEUE_LENGTH 128
#endif
typedef struct {
char buffer[RINGBUF_QUEUE_LENGTH];
int head;
int tail;
volatile int head;
volatile int tail;
} Ring_buffer_t;
#define Ring_buffer_Initialize( _buffer ) \
@@ -27,16 +27,27 @@ typedef struct {
#define Ring_buffer_Is_empty( _buffer ) \
( (_buffer)->head == (_buffer)->tail )
#define Ring_buffer_Is_full( _buffer ) \
( (_buffer)->head == ((_buffer)->tail + 1) % RINGBUF_QUEUE_LENGTH )
#define Ring_buffer_Add_character( _buffer, _ch ) \
do { \
(_buffer)->buffer[ (_buffer)->tail ] = (_ch); \
(_buffer)->tail = ((_buffer)->tail+1) % RINGBUF_QUEUE_LENGTH; \
rtems_unsigned32 isrlevel; \
\
rtems_interrupt_disable( isrlevel ); \
(_buffer)->tail = ((_buffer)->tail+1) % RINGBUF_QUEUE_LENGTH; \
(_buffer)->buffer[ (_buffer)->tail ] = (_ch); \
rtems_interrupt_enable( isrlevel ); \
} while ( 0 )
#define Ring_buffer_Remove_character( _buffer, _ch ) \
do { \
(_ch) = (_buffer)->buffer[ (_buffer)->head ]; \
(_buffer)->head = ((_buffer)->head+1) % RINGBUF_QUEUE_LENGTH; \
rtems_unsigned32 isrlevel; \
\
rtems_interrupt_disable( isrlevel ); \
(_buffer)->head = ((_buffer)->head+1) % RINGBUF_QUEUE_LENGTH; \
(_ch) = (_buffer)->buffer[ (_buffer)->head ]; \
rtems_interrupt_enable( isrlevel ); \
} while ( 0 )
#endif
@@ -29,7 +29,7 @@
#include <rtems.h>
#include <bsp.h>
#include <rtems/libio.h>
#include <rtems/score/intthrd.h>
#include <rtems/intthrd.h>
#include <libcsupport.h>
@@ -243,19 +243,22 @@ bsp_pretasking_hook(void)
void
bsp_postdriver_hook(void)
{
int stdin_fd, stdout_fd, stderr_fd;
if ((stdin_fd = __open("/dev/tty00", O_RDONLY, 0)) == -1)
rtems_fatal_error_occurred('STD0');
if ((stdout_fd = __open("/dev/tty00", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred('STD1');
if ((stderr_fd = __open("/dev/tty00", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred('STD2');
if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2))
rtems_fatal_error_occurred('STIO');
int stdin_fd, stdout_fd, stderr_fd;
int error_code;
error_code = 'S' << 24 | 'T' << 16;
if ((stdin_fd = __open("/dev/console", O_RDONLY, 0)) == -1)
rtems_fatal_error_occurred( error_code | 'D' << 8 | '0' );
if ((stdout_fd = __open("/dev/console", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred( error_code | 'D' << 8 | '1' );
if ((stderr_fd = __open("/dev/console", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred( error_code | 'D' << 8 | '2' );
if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2))
rtems_fatal_error_occurred( error_code | 'I' << 8 | 'O' );
}
/*
+4 -12
View File
@@ -75,17 +75,6 @@ void Install_clock(
atexit( Clock_exit );
}
void ReInstall_clock(
rtems_isr_entry clock_isr
)
{
rtems_unsigned32 isrlevel = 0;
rtems_interrupt_disable( isrlevel );
(void) set_vector( clock_isr, CLOCK_VECTOR, 1 );
rtems_interrupt_enable( isrlevel );
}
void Clock_exit( void )
{
if ( BSP_Configuration.ticks_per_timeslice ) {
@@ -119,6 +108,7 @@ rtems_device_driver Clock_control(
void *pargp
)
{
rtems_unsigned32 isrlevel;
rtems_libio_ioctl_args_t *args = pargp;
if (args == 0)
@@ -135,7 +125,9 @@ rtems_device_driver Clock_control(
}
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
{
ReInstall_clock(args->buffer);
rtems_interrupt_disable( isrlevel );
(void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
rtems_interrupt_enable( isrlevel );
}
done:
@@ -122,18 +122,21 @@ void
bsp_postdriver_hook(void)
{
int stdin_fd, stdout_fd, stderr_fd;
int error_code;
error_code = 'S' << 24 | 'T' << 16;
if ((stdin_fd = __open("/dev/console", O_RDONLY, 0)) == -1)
rtems_fatal_error_occurred('STD0');
rtems_fatal_error_occurred( error_code | 'D' << 8 | '0' );
if ((stdout_fd = __open("/dev/console", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred('STD1');
rtems_fatal_error_occurred( error_code | 'D' << 8 | '1' );
if ((stderr_fd = __open("/dev/console", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred('STD2');
rtems_fatal_error_occurred( error_code | 'D' << 8 | '2' );
if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2))
rtems_fatal_error_occurred('STIO');
rtems_fatal_error_occurred( error_code | 'I' << 8 | 'O' );
}
int main(
+4 -12
View File
@@ -108,17 +108,6 @@ void Install_clock(
atexit( Clock_exit );
}
void ReInstall_clock(
rtems_isr_entry clock_isr
)
{
rtems_unsigned32 isrlevel = 0;
rtems_interrupt_disable( isrlevel );
(void) set_vector( clock_isr, CLOCK_VECTOR, 1 );
rtems_interrupt_enable( isrlevel );
}
void Clock_exit( void )
{
if ( BSP_Configuration.ticks_per_timeslice ) {
@@ -161,6 +150,7 @@ rtems_device_driver Clock_control(
void *pargp
)
{
rtems_unsigned32 isrlevel;
rtems_libio_ioctl_args_t *args = pargp;
if (args == 0)
@@ -177,7 +167,9 @@ rtems_device_driver Clock_control(
}
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
{
ReInstall_clock(args->buffer);
rtems_interrupt_disable( isrlevel );
(void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
rtems_interrupt_enable( isrlevel );
}
done:
@@ -129,18 +129,21 @@ void
bsp_postdriver_hook(void)
{
int stdin_fd, stdout_fd, stderr_fd;
int error_code;
error_code = 'S' << 24 | 'T' << 16;
if ((stdin_fd = __open("/dev/console", O_RDONLY, 0)) == -1)
rtems_fatal_error_occurred('STD0');
rtems_fatal_error_occurred( error_code | 'D' << 8 | '0' );
if ((stdout_fd = __open("/dev/console", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred('STD1');
rtems_fatal_error_occurred( error_code | 'D' << 8 | '1' );
if ((stderr_fd = __open("/dev/console", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred('STD2');
rtems_fatal_error_occurred( error_code | 'D' << 8 | '2' );
if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2))
rtems_fatal_error_occurred('STIO');
rtems_fatal_error_occurred( error_code | 'I' << 8 | 'O' );
}
/* This is the original command line passed from DOS */
+4 -8
View File
@@ -60,13 +60,6 @@ void Install_clock(
}
}
void ReInstall_clock(
rtems_isr_entry clock_isr
)
{
(void) set_vector( clock_isr, CLOCK_VECTOR, 1 );
}
void Clock_exit()
{
unsigned char *victimer;
@@ -105,6 +98,7 @@ rtems_device_driver Clock_control(
void *pargp
)
{
rtems_unsigned32 isrlevel;
rtems_libio_ioctl_args_t *args = pargp;
if (args == 0)
@@ -121,7 +115,9 @@ rtems_device_driver Clock_control(
}
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
{
ReInstall_clock(args->buffer);
rtems_interrupt_disable( isrlevel );
(void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
rtems_interrupt_enable( isrlevel );
}
done:
@@ -124,18 +124,21 @@ void
bsp_postdriver_hook(void)
{
int stdin_fd, stdout_fd, stderr_fd;
int error_code;
error_code = 'S' << 24 | 'T' << 16;
if ((stdin_fd = __open("/dev/console", O_RDONLY, 0)) == -1)
rtems_fatal_error_occurred('STD0');
rtems_fatal_error_occurred( error_code | 'D' << 8 | '0' );
if ((stdout_fd = __open("/dev/console", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred('STD1');
rtems_fatal_error_occurred( error_code | 'D' << 8 | '1' );
if ((stderr_fd = __open("/dev/console", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred('STD2');
rtems_fatal_error_occurred( error_code | 'D' << 8 | '2' );
if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2))
rtems_fatal_error_occurred('STIO');
rtems_fatal_error_occurred( error_code | 'I' << 8 | 'O' );
}
int main(
+4 -12
View File
@@ -97,17 +97,6 @@ void Install_clock(
}
}
void ReInstall_clock(
rtems_isr_entry clock_isr
)
{
rtems_unsigned32 isrlevel = 0 ;
rtems_interrupt_disable( isrlevel );
(void) set_vector( clock_isr, CLOCK_VECTOR, 1 );
rtems_interrupt_enable( isrlevel );
}
void Clock_exit( void )
{
rtems_unsigned8 data;
@@ -145,6 +134,7 @@ rtems_device_driver Clock_control(
void *pargp
)
{
rtems_unsigned32 isrlevel;
rtems_libio_ioctl_args_t *args = pargp;
if (args == 0)
@@ -161,7 +151,9 @@ rtems_device_driver Clock_control(
}
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
{
ReInstall_clock(args->buffer);
rtems_interrupt_disable( isrlevel );
(void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
rtems_interrupt_enable( isrlevel );
}
done:
@@ -123,18 +123,21 @@ void
bsp_postdriver_hook(void)
{
int stdin_fd, stdout_fd, stderr_fd;
int error_code;
error_code = 'S' << 24 | 'T' << 16;
if ((stdin_fd = __open("/dev/console", O_RDONLY, 0)) == -1)
rtems_fatal_error_occurred('STD0');
rtems_fatal_error_occurred( error_code | 'D' << 8 | '0' );
if ((stdout_fd = __open("/dev/console", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred('STD1');
rtems_fatal_error_occurred( error_code | 'D' << 8 | '1' );
if ((stderr_fd = __open("/dev/console", O_WRONLY, 0)) == -1)
rtems_fatal_error_occurred('STD2');
rtems_fatal_error_occurred( error_code | 'D' << 8 | '2' );
if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2))
rtems_fatal_error_occurred('STIO');
rtems_fatal_error_occurred( error_code | 'I' << 8 | 'O' );
}
int main(

Some files were not shown because too many files have changed in this diff Show More