From cb0d9a0747b1be84fb669b1c71e55bf0d860d2f8 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 9 Jun 2017 08:17:59 +0200 Subject: i386: Move _CPU_Context_Initialize() Update #2468. --- cpukit/score/cpu/i386/cpu.c | 56 +++++++++++++++++++++++++++++++++ cpukit/score/cpu/i386/rtems/score/cpu.h | 55 ++++++-------------------------- 2 files changed, 65 insertions(+), 46 deletions(-) diff --git a/cpukit/score/cpu/i386/cpu.c b/cpukit/score/cpu/i386/cpu.c index 447d8ae273..804afb1647 100644 --- a/cpukit/score/cpu/i386/cpu.c +++ b/cpukit/score/cpu/i386/cpu.c @@ -114,6 +114,62 @@ void _CPU_Initialize(void) #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 level; diff --git a/cpukit/score/cpu/i386/rtems/score/cpu.h b/cpukit/score/cpu/i386/rtems/score/cpu.h index ace26f396c..64f049ed0b 100644 --- a/cpukit/score/cpu/i386/rtems/score/cpu.h +++ b/cpukit/score/cpu/i386/rtems/score/cpu.h @@ -433,52 +433,15 @@ uint32_t _CPU_ISR_Get_level( void ); #ifndef ASM -/* - * 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. - */ - - - -#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) +void _CPU_Context_Initialize( + Context_Control *the_context, + void *stack_area_begin, + size_t stack_area_size, + uint32_t new_level, + void (*entry_point)( void ), + bool is_fp, + void *tls_area +); #define _CPU_Context_Restart_self( _the_context ) \ _CPU_Context_restore( (_the_context) ); -- cgit v1.2.3