Ignore:
Timestamp:
Nov 7, 2017, 3:08:12 PM (5 years ago)
Author:
alain
Message:

First implementation of fork/exec.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/tsar_mips32/core/hal_context.c

    r406 r407  
    4444
    4545/////////////////////////////////////////////////////////////////////////////////////////
    46 // This structuree defines the cpu_context for TSAR MIPS32.
    47 // These registers are saved/restored at each context switch.
     46// This structure defines the CPU context for TSAR MIPS32.
     47// The following registers are saved/restored at each context switch:
     48// - GPR : all, but (zero, k0, k1), plus (hi, lo)
     49// - CP0 : c0_th , c0_sr , C0_epc
     50// - CP2 : c2_ptpr , C2_mode
     51//
    4852// WARNING : check the two CONFIG_CPU_CTX_SIZE & CONFIG_FPU_CTX_SIZE configuration
    4953//           parameterss when modifying this structure.
     
    8589    uint32_t gp_28;      // slot 28
    8690        uint32_t sp_29;      // slot 29
    87         uint32_t fp_30;      // slot 30
     91        uint32_t s8_30;      // slot 30
    8892        uint32_t ra_31;      // slot 31
    8993
     
    108112
    109113/////////////////////////////////////////////////////////////////////////////////////////
    110 //        CPU context access functions
    111 /////////////////////////////////////////////////////////////////////////////////////////
    112 
    113 /////////////////////////////////////////////////////////////////////////////////////////
    114 // This function allocates and initializes the cpu_context stucture in thread descriptor.
    115 // The following context slots are initialised by this function:
    116 // GPR : a0_04 / sp_29 / fp_30 / ra_31
     114//        CPU context related functions
     115/////////////////////////////////////////////////////////////////////////////////////////
     116
     117
     118//////////////////////////////////////////////////
     119error_t hal_cpu_context_alloc( thread_t * thread )
     120{
     121    assert( (sizeof(hal_cpu_context_t) <= CONFIG_CPU_CTX_SIZE) , __FUNCTION__ ,
     122    "illegal CPU context size" );
     123
     124    // allocate memory for cpu_context
     125    kmem_req_t  req;
     126    req.type   = KMEM_CPU_CTX;
     127    req.flags  = AF_KERNEL | AF_ZERO;
     128
     129    hal_cpu_context_t * context = (hal_cpu_context_t *)kmem_alloc( &req );
     130    if( context == NULL ) return -1;
     131
     132    // link to thread
     133    thread->cpu_context = (void *)context;
     134    return 0;
     135
     136}   // end hal_cpu_context_alloc()
     137
     138///////////////////////////////////////////////////
     139// The following context slots are initialised :
     140// GPR : a0_04 / sp_29 / ra_31
    117141// CP0 : c0_sr / c0_th / c0_epc
    118142// CP2 : c2_ptpr / c2_mode
    119 /////////////////////////////////////////////////////////////////////////////////////////
     143///////////////////////////////////////////////////
    120144error_t hal_cpu_context_create( thread_t * thread )
    121145{
    122     kmem_req_t  req;
    123 
    124     assert( (sizeof(hal_cpu_context_t) <= CONFIG_CPU_CTX_SIZE) , __FUNCTION__ ,
    125     "inconsistent CPU context size" );
    126 
    127     context_dmsg("\n[DMSG] %s : enters for thread %x in process %x\n",
    128                  __FUNCTION__ , thread->trdid , thread->process->pid );
    129 
    130     // allocate memory for cpu_context
    131     req.type   = KMEM_CPU_CTX;
    132     req.flags  = AF_KERNEL | AF_ZERO;
    133 
    134     hal_cpu_context_t * context = (hal_cpu_context_t *)kmem_alloc( &req );
    135     if( context == NULL ) return ENOMEM;
    136 
    137     // set cpu context pointer in thread
    138     thread->cpu_context = (void*)context;
    139 
    140     // stack pointer, status register and mmu_mode depends on thread type
    141         uint32_t sp_29;
    142     uint32_t c0_sr;
    143     uint32_t c2_mode;
     146    // allocate memory for a CPU context
     147    error_t error = hal_cpu_context_alloc( thread );
     148
     149    if( error ) return error;
     150
     151    hal_cpu_context_t * context = (hal_cpu_context_t *)thread->cpu_context;
     152
     153    // initialisation depends on thread type
    144154    if( thread->type == THREAD_USER )
    145155    {
    146         sp_29   = ((uint32_t)thread->u_stack_base) + thread->u_stack_size;
    147         c0_sr   = SR_USR_MODE;
    148         c2_mode = 0xF;
     156        context->a0_04   = (uint32_t)thread->entry_args;
     157        context->sp_29   = (uint32_t)thread->u_stack_base + (uint32_t)thread->u_stack_size - 8;
     158        context->ra_31   = (uint32_t)&hal_kentry_eret;
     159        context->c0_epc  = (uint32_t)thread->entry_func;
     160        context->c0_sr   = SR_USR_MODE;
     161            context->c0_th   = (uint32_t)thread;
     162            context->c2_ptpr = (uint32_t)((thread->process->vmm.gpt.ppn) >> 1);
     163        context->c2_mode = 0xF;
    149164    }
    150     else
     165    else  // kernel thread
    151166    {
    152         sp_29   = ((uint32_t)thread->k_stack_base) + thread->k_stack_size;
    153         c0_sr   = SR_SYS_MODE;
    154         c2_mode = 0x3;
     167        context->a0_04   = (uint32_t)thread->entry_args;
     168        context->sp_29   = (uint32_t)thread->k_stack_base + (uint32_t)thread->k_stack_size - 8;
     169        context->ra_31   = (uint32_t)thread->entry_func;
     170        context->c0_sr   = SR_SYS_MODE;
     171            context->c0_th   = (uint32_t)thread;
     172            context->c2_ptpr = (uint32_t)((thread->process->vmm.gpt.ppn) >> 1);
     173        context->c2_mode = 0x3;
    155174    }
    156175
    157     // align stack pointer on a double word boundary
    158         sp_29 = (sp_29 - 8) & (~ 0x7);
    159 
    160     // initialise context
    161     context->a0_04      = (uint32_t)thread->entry_args;
    162         context->sp_29      = sp_29;
    163         context->fp_30      = sp_29;                               // TODO check this [AG]
    164     context->ra_31      = (uint32_t)&hal_kentry_eret;
    165     context->c0_epc     = (uint32_t)thread->entry_func;
    166         context->c0_sr      = c0_sr;
    167         context->c0_th      = (uint32_t)thread;
    168         context->c2_ptpr    = (uint32_t)((thread->process->vmm.gpt.ppn) >> 1);
    169         context->c2_mode    = c2_mode;
    170 
    171     context_dmsg("\n[DMSG] %s : exit for thread %x in process %x\n"
     176context_dmsg("\n[DBG] %s : thread %x in process %x\n"
    172177                 " - a0   = %x\n"
    173178                 " - sp   = %x\n"
    174                  " - fp   = %x\n"
    175179                 " - ra   = %x\n"
    176180                 " - sr   = %x\n"
     
    180184                 " - mode = %x\n", 
    181185                 __FUNCTION__ , thread->trdid , thread->process->pid,
    182                  context->a0_04, context->sp_29, context->fp_30, context->ra_31,
     186                 context->a0_04, context->sp_29, context->ra_31,
    183187                 context->c0_sr, context->c0_th, context->c0_epc,
    184188                 context->c2_ptpr, context->c2_mode );
     
    201205           ctx->c2_ptpr , ctx->c2_mode );
    202206
    203 }  // end hal_context_display()
    204 
    205 /////////////////////////////////////////////////////////////////////////////////////////
    206 // These registers are saved/restored to/from CPU context defined by <ctx> argument.
    207 // - GPR : all, but (zero, k0, k1), plus (hi, lo)
    208 // - CP0 : c0_th , c0_sr , C0_epc
    209 // - CP2 : c2_ptpr , C2_mode
    210 /////////////////////////////////////////////////////////////////////////////////////////
    211 // old_thread  : pointer on current thread descriptor
    212 // new_thread  : pointer on new thread descriptor
    213 /////////////////////////////////////////////////////////////////////////////////////////
    214 void hal_cpu_context_switch( thread_t * old_thread,
    215                              thread_t * new_thread )
    216 {
    217     hal_cpu_context_t * ctx_old = old_thread->cpu_context;
    218     hal_cpu_context_t * ctx_new = new_thread->cpu_context;
    219 
    220     #if CONFIG_CONTEXT_DEBUG
    221     hal_cpu_context_display( old_thread );
    222     hal_cpu_context_display( new_thread );
    223     #endif
    224 
    225     // reset loadable field in new thread descriptor
    226     new_thread->flags &= ~THREAD_FLAG_LOADABLE;
    227 
    228     hal_do_switch( ctx_old , ctx_new );
    229 }
    230 
    231 /////////////////////////////////////////////
    232 error_t hal_cpu_context_copy( thread_t * dst,
    233                               thread_t * src )
    234 {
    235     kmem_req_t  req;
    236 
    237     // allocate memory for dst cpu_context
    238     req.type   = KMEM_CPU_CTX;
    239     req.size   = sizeof(hal_cpu_context_t);
    240     req.flags  = AF_KERNEL | AF_ZERO;
    241 
    242     hal_cpu_context_t * dst_context = (hal_cpu_context_t *)kmem_alloc( &req );
    243     if( dst_context == NULL ) return ENOMEM;
    244 
    245     // set cpu context pointer in dst thread
    246     dst->cpu_context = dst_context;
    247 
    248     // get cpu context pointer from src thread
    249     hal_cpu_context_t * src_context = src->cpu_context;
    250 
    251     // copy CPU context from src to dst
    252     memcpy( dst_context , src_context , sizeof(hal_cpu_context_t) );
    253 
    254     return 0;
    255 
    256 }  // end hal_cpu_context_copy()
     207}  // end hal_cpu_context_display()
    257208
    258209/////////////////////////////////////////////////
     
    268219
    269220
    270 ///////////////////////////////////////////////////
    271 error_t hal_fpu_context_create( thread_t * thread )
    272 {
     221
     222
     223
     224//////////////////////////////////////////////////
     225error_t hal_fpu_context_alloc( thread_t * thread )
     226{
     227    assert( (sizeof(hal_fpu_context_t) <= CONFIG_FPU_CTX_SIZE) , __FUNCTION__ ,
     228    "illegal CPU context size" );
     229
     230    // allocate memory for fpu_context
    273231    kmem_req_t  req;
    274 
    275     assert( (sizeof(hal_fpu_context_t) <= CONFIG_FPU_CTX_SIZE) , __FUNCTION__ ,
    276     "inconsistent FPU context size" );
    277 
    278     // allocate memory for uzone
    279232    req.type   = KMEM_FPU_CTX;
    280233    req.flags  = AF_KERNEL | AF_ZERO;
    281234
    282235    hal_fpu_context_t * context = (hal_fpu_context_t *)kmem_alloc( &req );
    283     if( context == NULL ) return ENOMEM;
    284 
    285     // set fpu context pointer in thread
    286     thread->fpu_context = (void*)context;
    287    
     236    if( context == NULL ) return -1;
     237
     238    // link to thread
     239    thread->fpu_context = (void *)context;
    288240    return 0;
    289 }  // hal_fpu_context_create()
    290 
    291 /////////////////////////////////////////////
    292 error_t hal_fpu_context_copy( thread_t * dst,
    293                               thread_t * src )
    294 {
    295     kmem_req_t  req;
    296 
    297     // allocate memory for dst fpu_context
    298     req.type   = KMEM_FPU_CTX;
    299     req.flags  = AF_KERNEL | AF_ZERO;
    300 
    301     hal_fpu_context_t * dst_context = (hal_fpu_context_t *)kmem_alloc( &req );
    302     if( dst_context == NULL ) return ENOMEM;
    303 
    304     // set fpu context pointer in dst thread
    305     dst->fpu_context = (void*)dst_context;
    306 
    307     // get fpu context pointer from src thread
     241
     242}   // end hal_fpu_context_alloc()
     243
     244//////////////////////////////////////////
     245void hal_fpu_context_copy( thread_t * dst,
     246                           thread_t * src )
     247{
     248    assert( (src != NULL) , __FUNCTION__ , "src thread pointer is NULL\n");
     249    assert( (dst != NULL) , __FUNCTION__ , "dst thread pointer is NULL\n");
     250
     251    // get fpu context pointers
    308252    hal_fpu_context_t * src_context = src->fpu_context;
     253    hal_fpu_context_t * dst_context = dst->fpu_context;
    309254
    310255    // copy CPU context from src to dst
    311256    memcpy( dst_context , src_context , sizeof(hal_fpu_context_t) );
    312257
    313     return 0;
    314258}  // end hal_fpu_context_copy()
    315259
     
    413357} // end hal_cpu_context_restore()
    414358
    415 /////////////////////////////////////
    416 void hal_fpu_context_dup( xptr_t dst,
    417                           xptr_t src )
    418 {
    419         hal_remote_memcpy( dst , src , sizeof(hal_fpu_context_t) );
    420 }
    421 
     359
Note: See TracChangeset for help on using the changeset viewer.