📄 cpu.h
字号:
#endif /* This is what is left out of the primary contexts */ unsigned32 gpr0; unsigned32 gpr2; /* play safe */ unsigned32 gpr3; unsigned32 gpr4; unsigned32 gpr5; unsigned32 gpr6; unsigned32 gpr7; unsigned32 gpr8; unsigned32 gpr9; unsigned32 gpr10; unsigned32 gpr11; unsigned32 gpr12; unsigned32 gpr13; /* Play safe */ unsigned32 gpr28; /* For internal use by the IRQ handler */ unsigned32 gpr29; /* For internal use by the IRQ handler */ unsigned32 gpr30; /* For internal use by the IRQ handler */ unsigned32 gpr31; /* For internal use by the IRQ handler */ unsigned32 cr; /* Bits of this are volatile, so no-one may save */ unsigned32 ctr; unsigned32 xer; unsigned32 lr; unsigned32 pc; unsigned32 msr; unsigned32 pad[3];} CPU_Interrupt_frame;/* * The following table contains the information required to configure * the PowerPC processor specific parameters. */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 */ unsigned32 clicks_per_usec; /* Timer clicks per microsecond */ void (*spurious_handler)(unsigned32 vector, CPU_Interrupt_frame *); boolean exceptions_in_RAM; /* TRUE if in RAM */#if (defined(ppc403) || defined(ppc405) || defined(mpc860) || defined(mpc821)) unsigned32 serial_per_sec; /* Serial clocks per second */ boolean serial_external_clock; boolean serial_xon_xoff; boolean serial_cts_rts; unsigned32 serial_rate; unsigned32 timer_average_overhead; /* Average overhead of timer in ticks */ unsigned32 timer_least_valid; /* Least valid number from timer */ boolean timer_internal_clock; /* TRUE, when timer runs with CPU clk */#endif#if (defined(mpc860) || defined(mpc821)) unsigned32 clock_speed; /* Speed of CPU in Hz */#endif} rtems_cpu_table;/* * Macros to access required entires in the CPU Table are in * the file rtems/system.h. *//* * Macros to access PowerPC specific additions to the CPU Table */#define rtems_cpu_configuration_get_clicks_per_usec() \ (_CPU_Table.clicks_per_usec)#define rtems_cpu_configuration_get_spurious_handler() \ (_CPU_Table.spurious_handler)#define rtems_cpu_configuration_get_exceptions_in_ram() \ (_CPU_Table.exceptions_in_RAM)#if (defined(ppc403) || defined(ppc405) || defined(mpc860) || defined(mpc821))#define rtems_cpu_configuration_get_serial_per_sec() \ (_CPU_Table.serial_per_sec)#define rtems_cpu_configuration_get_serial_external_clock() \ (_CPU_Table.serial_external_clock)#define rtems_cpu_configuration_get_serial_xon_xoff() \ (_CPU_Table.serial_xon_xoff)#define rtems_cpu_configuration_get_serial_cts_rts() \ (_CPU_Table.serial_cts_rts)#define rtems_cpu_configuration_get_serial_rate() \ (_CPU_Table.serial_rate)#define rtems_cpu_configuration_get_timer_average_overhead() \ (_CPU_Table.timer_average_overhead)#define rtems_cpu_configuration_get_timer_least_valid() \ (_CPU_Table.timer_least_valid)#define rtems_cpu_configuration_get_timer_internal_clock() \ (_CPU_Table.timer_internal_clock)#endif#if (defined(mpc860) || defined(mpc821))#define rtems_cpu_configuration_get_clock_speed() \ (_CPU_Table.clock_speed)#endif/* * The following type defines an entry in the PPC'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 stwu_r1; /* stwu %r1, -(??+IP_END)(%1)*/ unsigned32 stw_r0; /* stw %r0, IP_0(%r1) */ unsigned32 li_r0_IRQ; /* li %r0, _IRQ */ unsigned32 b_Handler; /* b PROC (_ISR_Handler) */} CPU_Trap_table_entry;/* * This variable is optional. It is used on CPUs on which it is difficult * to generate an "uninitialized" FP context. It is filled in by * _CPU_Initialize and copied into the task's FP context area during * _CPU_Context_Initialize. *//* EXTERN Context_Control_fp _CPU_Null_fp_context; *//* * On some CPUs, RTEMS supports a software managed interrupt stack. * 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. * * NOTE: These two variables are required if the macro * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE. */SCORE_EXTERN void *_CPU_Interrupt_stack_low;SCORE_EXTERN void *_CPU_Interrupt_stack_high;/* * With some compilation systems, it is difficult if not impossible to * call a high-level language routine from assembly language. This * is especially true of commercial Ada compilers and name mangling * C++ ones. This variable can be optionally defined by the CPU porter * and contains the address of the routine _Thread_Dispatch. This * can make it easier to invoke that routine at the end of the interrupt * sequence (if a dispatch is necessary). *//* EXTERN void (*_CPU_Thread_dispatch_pointer)(); *//* * Nothing prevents the porter from declaring more CPU specific variables. */SCORE_EXTERN struct { unsigned32 volatile* Nest_level; unsigned32 volatile* Disable_level; void *Vector_table; void *Stack;#if (PPC_ABI == PPC_ABI_POWEROPEN) unsigned32 Dispatch_r2;#else unsigned32 Default_r2;#if (PPC_ABI != PPC_ABI_GCC27) unsigned32 Default_r13;#endif#endif volatile boolean *Switch_necessary; boolean *Signal; unsigned32 msr_initial;} _CPU_IRQ_info CPU_STRUCTURE_ALIGNMENT;/* * The size of the floating point context area. On some CPUs this * will not be a "sizeof" because the format of the floating point * area is not defined -- only the size is. This is usually on * CPUs with a "floating point save context" instruction. */#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )/* * (Optional) # of bytes for libmisc/stackchk to check * If not specifed, then it defaults to something reasonable * for most architectures. */#define CPU_STACK_CHECK_SIZE (128)/* * 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 0/* * This defines the number of entries in the ISR_Vector_table managed * by RTEMS. */#define CPU_INTERRUPT_NUMBER_OF_VECTORS (PPC_INTERRUPT_MAX)#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (PPC_INTERRUPT_MAX - 1)/* * 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 TRUE/* * Should be large enough to run all RTEMS tests. This insures * that a "reasonable" small application should not have any problems. */#define CPU_STACK_MINIMUM_SIZE (1024*8)/* * CPU's worst alignment requirement for data types on a byte boundary. This * alignment does not take into account the requirements for the stack. */#define CPU_ALIGNMENT (PPC_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_HEAP_ALIGNMENT (PPC_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 (PPC_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. */#define CPU_STACK_ALIGNMENT (PPC_STACK_ALIGNMENT)/* * ISR handler macros */void _CPU_Initialize_vectors(void);/* * Disable all interrupts for an RTEMS critical section. The previous * level is returned in _isr_cookie. */#define _CPU_MSR_Value( _msr_value ) \ do { \ _msr_value = 0; \ asm volatile ("mfmsr %0" : "=&r" ((_msr_value)) : "0" ((_msr_value))); \ } while (0)#define _CPU_MSR_SET( _msr_value ) \{ asm volatile ("mtmsr %0" : "=&r" ((_msr_value)) : "0" ((_msr_value))); }#if 0#define _CPU_ISR_Disable( _isr_cookie ) \ { register unsigned int _disable_mask = PPC_MSR_DISABLE_MASK; \ _isr_cookie = 0; \ asm volatile ( "mfmsr %0" : \ "=r" ((_isr_cookie)) : \ "0" ((_isr_cookie)) \ ); \ asm volatile ( "andc %1,%0,%1" : \ "=r" ((_isr_cookie)), "=&r" ((_disable_mask)) : \ "0" ((_isr_cookie)), "1" ((_disable_mask)) \ ); \ asm volatile ( "mtmsr %1" : \ "=r" ((_disable_mask)) : \ "0" ((_disable_mask)) \ ); \ }#endif#define _CPU_ISR_Disable( _isr_cookie ) \ { register unsigned int _disable_mask = PPC_MSR_DISABLE_MASK; \ _isr_cookie = 0; \ asm volatile ( \ "mfmsr %0; andc %1,%0,%1; mtmsr %1" : \ "=&r" ((_isr_cookie)), "=&r" ((_disable_mask)) : \ "0" ((_isr_cookie)), "1" ((_disable_mask)) \ ); \ }/* * Enable interrupts to the previous level (returned by _CPU_ISR_Disable). * This indicates the end of an RTEMS critical section. The parameter * _isr_cookie is not modified. */#define _CPU_ISR_Enable( _isr_cookie ) \ { \ asm volatile ( "mtmsr %0" : \ "=r" ((_isr_cookie)) : \ "0" ((_isr_cookie))); \ }/* * This temporarily restores the interrupt to _isr_cookie before immediately * disabling them again. This is used to divide long RTEMS critical * sections into two or more parts. The parameter _isr_cookie is not * modified. * * NOTE: The version being used is not very optimized but it does * not trip a problem in gcc where the disable mask does not * get loaded. Check this for future (post 10/97 gcc versions. */#define _CPU_ISR_Flash( _isr_cookie ) \ { register unsigned int _disable_mask = PPC_MSR_DISABLE_MASK; \ asm volatile ( \ "mtmsr %0; andc %1,%0,%1; mtmsr %1" : \ "=r" ((_isr_cookie)), "=r" ((_disable_mask)) : \ "0" ((_isr_cookie)), "1" ((_disable_mask)) \ ); \ }/* * 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 generic fashion are undefined. Someday, * it would be nice if these were "mapped" by the application * via a callout. For example, m68k has 8 levels 0 - 7, levels * 8 - 255 would be available for bsp/application specific meaning. * This could be used to manage a programmable interrupt controller * via the rtems_task_mode directive. */unsigned32 _CPU_ISR_Calculate_level( unsigned32 new_level
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -