/* * Function: void CPU_ContextInit(OS_context_t *the_context, uint32 *stack_base, uint32 size, uint32 new_level, void *entry_point) * * This function initializes the thread context */ void CPU_ContextInit(CPU_context_t *the_context, uint8_t *stack_base, uint32_t size, uint32_t new_level, void *entry_point) { uint32_t stack_high; /* highest "stack aligned" address */ uint32_t the_size; uint32_t tmp_psr; /* * On CPUs with stacks which grow down (i.e. SPARC), we build the stack * based on the stack_high address. */ stack_high = (uint32_t)((stack_base) + size); stack_high &= ~(CPU_STACK_ALIGNMENT - 1); the_size = size & ~(CPU_STACK_ALIGNMENT - 1); /* * See the README in this directory for a diagram of the stack. */ // the_context->i6_fp = stack_high - CPU_MINIMUM_STACK_FRAME_SIZE; // the_context->o6_sp = the_context->i6_fp - CPU_MINIMUM_STACK_FRAME_SIZE; the_context->i6_fp = stack_high - CPU_MINIMUM_STACK_FRAME_SIZE; the_context->l1 = ((uint32_t) entry_point); the_context->l2 = ((uint32_t) entry_point) + 4; /* * 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 &= ~PSR_PIL; tmp_psr |= (new_level << 8) & PSR_PIL; tmp_psr &= ~PSR_EF; /* disabled by default */ the_context->psr = tmp_psr; }
void _CPU_Initialize(void) { #if (SPARC_HAS_FPU == 1) && !defined(SPARC_USE_SAFE_FP_SUPPORT) Context_Control_fp *pointer; uint32_t psr; sparc_get_psr( psr ); psr |= SPARC_PSR_EF_MASK; sparc_set_psr( psr ); /* * 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 ); #endif }
void _CPU_Context_Initialize( Context_Control *the_context, uint32_t *stack_base, uint32_t size, uint32_t new_level, void *entry_point, bool is_fp, void *tls_area ) { uint32_t stack_high; /* highest "stack aligned" address */ uint32_t tmp_psr; /* * On CPUs with stacks which grow down (i.e. SPARC), we build the stack * based on the stack_high address. */ stack_high = ((uint32_t)(stack_base) + size); stack_high &= ~(CPU_STACK_ALIGNMENT - 1); /* * See the README in this directory for a diagram of the stack. */ the_context->o7 = ((uint32_t) entry_point) - 8; the_context->o6_sp = stack_high - SPARC_MINIMUM_STACK_FRAME_SIZE; the_context->i6_fp = 0; /* * 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_PSR_PIL_MASK; tmp_psr |= (new_level << 8) & SPARC_PSR_PIL_MASK; tmp_psr &= ~SPARC_PSR_EF_MASK; /* disabled by default */ /* _CPU_Context_restore_heir() relies on this */ _Assert( ( tmp_psr & SPARC_PSR_ET_MASK ) != 0 ); #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; /* * Since THIS thread is being created, there is no way that THIS * thread can have an _ISR_Dispatch stack frame on its stack. */ the_context->isr_dispatch_disable = 0; if ( tls_area != NULL ) { void *tcb = _TLS_TCB_after_TLS_block_initialize( tls_area ); the_context->g7 = (uintptr_t) tcb; } }