📄 cpu.h
字号:
typedef struct { void (*pretasking_hook)( void ); void (*predriver_hook)( void ); void (*postdriver_hook)( void ); void (*idle_task)( void ); boolean do_zero_of_workspace; unsigned32 idle_task_stack_size; unsigned32 interrupt_stack_size; unsigned32 extra_mpci_receive_server_stack; void * (*stack_allocate_hook)( unsigned32 ); void (*stack_free_hook)( void* ); /* end of fields required on all CPUs */} rtems_cpu_table;/* * Macros to access required entires in the CPU Table are in * the file rtems/system.h. *//* * Macros to access SPARC specific additions to the CPU Table *//* There are no CPU specific additions to the CPU Table for this port. *//* * This variable is contains the initialize context for the FP unit. * It is filled in by _CPU_Initialize and copied into the task's FP * context area during _CPU_Context_Initialize. */SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context CPU_STRUCTURE_ALIGNMENT;/* * This stack is allocated by the Interrupt Manager and the switch * is performed in _ISR_Handler. These variables contain pointers * to the lowest and highest addresses in the chunk of memory allocated * for the interrupt stack. Since it is unknown whether the stack * grows up or down (in general), this give the CPU dependent * code the option of picking the version it wants to use. Thus * both must be present if either is. * * The SPARC supports a software based interrupt stack and these * are required. */SCORE_EXTERN void *_CPU_Interrupt_stack_low;SCORE_EXTERN void *_CPU_Interrupt_stack_high;/* * 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 { unsigned32 mov_psr_l0; /* mov %psr, %l0 */ unsigned32 sethi_of_handler_to_l4; /* sethi %hi(_handler), %l4 */ unsigned32 jmp_to_low_of_handler_plus_l4; /* jmp %l4 + %lo(_handler) */ unsigned32 mov_vector_l3; /* 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#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)/* * 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 insures * 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)/* * 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/* * This number corresponds to the byte alignment requirement for the * stack. This alignment requirement may be stricter than that for the * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT * is strict enough for the stack, then this should be set to 0. * * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT. * * The alignment restrictions for the SPARC are not that strict but this * should unsure that the stack is always sufficiently alignment that the * window overflow, underflow, and flush routines can use double word loads * and stores. */#define CPU_STACK_ALIGNMENT 16#ifndef ASMextern unsigned int sparc_disable_interrupts();extern void sparc_enable_interrupts();/* * 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 ) /* * 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) unsigned32 _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 * * NOTE: Implemented as a subroutine for the SPARC port. */void _CPU_Context_Initialize( Context_Control *the_context, unsigned32 *stack_base, unsigned32 size, unsigned32 new_level, void *entry_point, boolean is_fp);/* * 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) );/* * The FP context area for the SPARC is a simple structure and nothing * special is required to find the "starting load point" */#define _CPU_Context_Fp_start( _base, _offset ) \ ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )/* * This routine initializes the FP context area passed to it to. * * The SPARC allows us to use the simple initialization model * in which an "initial" FP context was saved into _CPU_Null_fp_context * at CPU initialization and it is simply copied into the destination * context. */#define _CPU_Context_Initialize_fp( _destination ) \ do { \ *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \ } 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. */#define _CPU_Fatal_halt( _error ) \ do { \ unsigned32 level; \ \ level = sparc_disable_interrupts(); \ asm volatile ( "mov %0, %%g1 " : "=r" (level) : "0" (level) ); \ while (1); /* loop forever */ \ } while (0)/* end of Fatal Error manager macros *//* Bitfield handler macros *//* * The SPARC port uses the generic C algorithm for bitfield scan if the * CPU model does not have a scan instruction. */#if ( SPARC_HAS_BITSCAN == 0 )#define CPU_USE_GENERIC_BITFIELD_CODE TRUE#define CPU_USE_GENERIC_BITFIELD_DATA TRUE#else#error "scan instruction not currently supported by RTEMS!!"#endif/* end of Bitfield handler macros *//* Priority handler handler macros *//* * The SPARC port uses the generic C algorithm for bitfield scan if the * CPU model does not have a scan instruction. */#if ( SPARC_HAS_BITSCAN == 1 )#error "scan instruction not currently supported by RTEMS!!"#endif/* end of Priority handler macros *//* functions *//* * _CPU_Initialize * * This routine performs CPU dependent initialization. */void _CPU_Initialize( rtems_cpu_table *cpu_table, void (*thread_dispatch));/* * _CPU_ISR_install_raw_handler * * This routine installs new_handler to be directly called from the trap * table. */ void _CPU_ISR_install_raw_handler( unsigned32 vector, proc_ptr new_handler, proc_ptr *old_handler);/* * _CPU_ISR_install_vector * * This routine installs an interrupt vector. */void _CPU_ISR_install_vector( unsigned32 vector, proc_ptr new_handler, proc_ptr *old_handler);#if (CPU_PROVIDES_IDLE_THREAD_BODY == TRUE) /* * _CPU_Thread_Idle_body * * Some SPARC implementations have low power, sleep, or idle modes. This * tries to take advantage of those models. */ void _CPU_Thread_Idle_body( void ); #endif /* CPU_PROVIDES_IDLE_THREAD_BODY *//* * _CPU_Context_switch * * This routine switches from the run context to the heir context. */void _CPU_Context_switch( Context_Control *run, Context_Control *heir);/* * _CPU_Context_restore * * This routine is generally used only to restart self in an * efficient manner. */void _CPU_Context_restore( Context_Control *new_context);/* * _CPU_Context_save_fp * * This routine saves the floating point context passed to it. */void _CPU_Context_save_fp( void **fp_context_ptr);/* * _CPU_Context_restore_fp * * This routine restores the floating point context passed to it. */void _CPU_Context_restore_fp( void **fp_context_ptr);/* * CPU_swap_u32 * * The following routine swaps the endian format of an unsigned int. * It must be static because it is referenced indirectly. * * 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 unsigned int CPU_swap_u32( unsigned int value){ unsigned32 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 );}#define CPU_swap_u16( value ) \ (((value&0xff) << 8) | ((value >> 8)&0xff))#endif ASM#ifdef __cplusplus}#endif#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -