forked from Imagelibrary/rtems
@@ -114,6 +114,62 @@ void _CPU_Initialize(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stack alignment note:
|
||||||
|
*
|
||||||
|
* We want the stack to look to the '_entry_point' routine
|
||||||
|
* like an ordinary stack frame as if '_entry_point' was
|
||||||
|
* called from C-code.
|
||||||
|
* Note that '_entry_point' is jumped-to by the 'ret'
|
||||||
|
* instruction returning from _CPU_Context_switch() or
|
||||||
|
* _CPU_Context_restore() thus popping the _entry_point
|
||||||
|
* from the stack.
|
||||||
|
* However, _entry_point expects a frame to look like this:
|
||||||
|
*
|
||||||
|
* args [_Thread_Handler expects no args, however]
|
||||||
|
* ------ (alignment boundary)
|
||||||
|
* SP-> return_addr return here when _entry_point returns which (never happens)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Hence we must initialize the stack as follows
|
||||||
|
*
|
||||||
|
* [arg1 ]: n/a
|
||||||
|
* [arg0 (aligned)]: n/a
|
||||||
|
* [ret. addr ]: NULL
|
||||||
|
* SP-> [jump-target ]: _entry_point
|
||||||
|
*
|
||||||
|
* When Context_switch returns it pops the _entry_point from
|
||||||
|
* the stack which then finds a standard layout.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _CPU_Context_Initialize(
|
||||||
|
Context_Control *the_context,
|
||||||
|
void *_stack_base,
|
||||||
|
size_t _size,
|
||||||
|
uint32_t _isr,
|
||||||
|
void (*_entry_point)( void ),
|
||||||
|
bool is_fp,
|
||||||
|
void *tls_area
|
||||||
|
)
|
||||||
|
{
|
||||||
|
uint32_t _stack;
|
||||||
|
|
||||||
|
(void) is_fp; /* avoid warning for being unused */
|
||||||
|
|
||||||
|
if ( _isr ) {
|
||||||
|
the_context->eflags = CPU_EFLAGS_INTERRUPTS_OFF;
|
||||||
|
} else {
|
||||||
|
the_context->eflags = CPU_EFLAGS_INTERRUPTS_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
_stack = ((uint32_t)(_stack_base)) + (_size);
|
||||||
|
_stack &= ~ (CPU_STACK_ALIGNMENT - 1);
|
||||||
|
_stack -= 2*sizeof(proc_ptr*); /* see above for why we need to do this */
|
||||||
|
*((proc_ptr *)(_stack)) = (_entry_point);
|
||||||
|
the_context->ebp = (void *) 0;
|
||||||
|
the_context->esp = (void *) _stack;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t _CPU_ISR_Get_level( void )
|
uint32_t _CPU_ISR_Get_level( void )
|
||||||
{
|
{
|
||||||
uint32_t level;
|
uint32_t level;
|
||||||
|
|||||||
@@ -433,52 +433,15 @@ uint32_t _CPU_ISR_Get_level( void );
|
|||||||
|
|
||||||
#ifndef ASM
|
#ifndef ASM
|
||||||
|
|
||||||
/*
|
void _CPU_Context_Initialize(
|
||||||
* Stack alignment note:
|
Context_Control *the_context,
|
||||||
*
|
void *stack_area_begin,
|
||||||
* We want the stack to look to the '_entry_point' routine
|
size_t stack_area_size,
|
||||||
* like an ordinary stack frame as if '_entry_point' was
|
uint32_t new_level,
|
||||||
* called from C-code.
|
void (*entry_point)( void ),
|
||||||
* Note that '_entry_point' is jumped-to by the 'ret'
|
bool is_fp,
|
||||||
* instruction returning from _CPU_Context_switch() or
|
void *tls_area
|
||||||
* _CPU_Context_restore() thus popping the _entry_point
|
);
|
||||||
* from the stack.
|
|
||||||
* However, _entry_point expects a frame to look like this:
|
|
||||||
*
|
|
||||||
* args [_Thread_Handler expects no args, however]
|
|
||||||
* ------ (alignment boundary)
|
|
||||||
* SP-> return_addr return here when _entry_point returns which (never happens)
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Hence we must initialize the stack as follows
|
|
||||||
*
|
|
||||||
* [arg1 ]: n/a
|
|
||||||
* [arg0 (aligned)]: n/a
|
|
||||||
* [ret. addr ]: NULL
|
|
||||||
* SP-> [jump-target ]: _entry_point
|
|
||||||
*
|
|
||||||
* When Context_switch returns it pops the _entry_point from
|
|
||||||
* the stack which then finds a standard layout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
|
|
||||||
_isr, _entry_point, _is_fp, _tls_area ) \
|
|
||||||
do { \
|
|
||||||
uint32_t _stack; \
|
|
||||||
\
|
|
||||||
(void) _is_fp; /* avoid warning for being unused */ \
|
|
||||||
if ( (_isr) ) (_the_context)->eflags = CPU_EFLAGS_INTERRUPTS_OFF; \
|
|
||||||
else (_the_context)->eflags = CPU_EFLAGS_INTERRUPTS_ON; \
|
|
||||||
\
|
|
||||||
_stack = ((uint32_t)(_stack_base)) + (_size); \
|
|
||||||
_stack &= ~ (CPU_STACK_ALIGNMENT - 1); \
|
|
||||||
_stack -= 2*sizeof(proc_ptr*); /* see above for why we need to do this */ \
|
|
||||||
*((proc_ptr *)(_stack)) = (_entry_point); \
|
|
||||||
(_the_context)->ebp = (void *) 0; \
|
|
||||||
(_the_context)->esp = (void *) _stack; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define _CPU_Context_Restart_self( _the_context ) \
|
#define _CPU_Context_Restart_self( _the_context ) \
|
||||||
_CPU_Context_restore( (_the_context) );
|
_CPU_Context_restore( (_the_context) );
|
||||||
|
|||||||
Reference in New Issue
Block a user