Changeset 625 for trunk/hal


Ignore:
Timestamp:
Apr 10, 2019, 10:09:39 AM (6 years ago)
Author:
alain
Message:

Fix a bug in the vmm_remove_vseg() function: the physical pages
associated to an user DATA vseg were released to the kernel when
the target process descriptor was in the reference cluster.
This physical pages release should be done only when the page
forks counter value is zero.
All other modifications are cosmetic.

Location:
trunk/hal
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/generic/hal_context.h

    r457 r625  
    22 * hal_context.h - Generic Thread Context Access API definition.
    33 *
    4  * Author  Alain Greiner    (2016)
     4 * Author  Alain Greiner    (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3131// and hal_fpu_context_t, defined in hal_context.c file, that are accessed with generic
    3232// void* pointers stored in the thread descriptor.
    33 // - the "hal_context_t" struct is used for the CPU registers values at context switch.
    34 // - the "hal_fpu_context_t" struct is used for the FPU registers when required.
     33// - the "hal_cpu_context_t" struct saves the CPU registers values at context switch.
     34// - the "hal_fpu_context_t" struct saves the FPU registers values at FPU switch.
    3535//////////////////////////////////////////////////////////////////////////////////////////
    3636
     
    5656
    5757/****************************************************************************************
    58  * This function is used to implement the fork() system call.
    59  * 1) It saves in a remote (child) thread CPU context the current CPU registers values.
    60  *    Three slots are not simple copies of the parent registers values :
    61  *    - the thread pointer is set to the child thread local pointer.
    62  *    - the stack pointer is set to parrent SP + (child_base - parent_base).
    63  *    - the status register is set to kernel mode with IRQ disabled.
    64  * 2) It copies the content of the calling (parent) thread kernel_stack,
    65  *    to the remote (child) thread kernel_stack.
     58 * This function is called the sys_fork() function to complete the fork mechanism.
     59 * It is called by th local parent thread to initialize the CPU context of the remote
     60 * child thread, identified by the <thread_xp> argument.
     61 * It makes three actions:
     62 * 1) It copies the current values of the CPU registers of the core running the parent
     63 *    thread to the remote child CPU context.
     64 * 2) It patches four slots of this remote child CPU context:
     65 *    - the c0_th   slot is set to the child thread descriptor pointer.
     66 *    - the sp_29   slot is set to the child kernel stack pointer.
     67 *    - the c0_sr   slot is set to kernel mode with IRQ disabled.
     68 *    - the c2_ptpr slot is set to the child process GPT value.
     69 * 3) It copies the content of the parent thread kernel_stack, to the child thread
     70 *    kernel_stack, because the COW mechanism is not available on architectures where
     71 *    the data MMU is de-activated in kernel mode.
    6672 ****************************************************************************************
    67  * @ thread_xp  : extended pointer on the remote thread descriptor.
     73 * @ thread_xp  : extended pointer on the child thread descriptor.
    6874 ***************************************************************************************/
    6975void hal_cpu_context_fork( xptr_t    thread_xp );
  • trunk/hal/generic/hal_gpt.h

    r624 r625  
    167167
    168168/****************************************************************************************
    169  * This function is used to implement the "fork" system call: It copies one GPT entry
    170  * identified by the <vpn> argument, from a remote <src_gpt_xp> to a local <dst_gpt>.
     169 * This function is used to implement the "fork" system call: It copies a remote
     170 * source PTE, identified by the <src_gpt_xp> and <src_vpn> arguments, to a local
     171 * destination PTE, identified by the <dst_gpt> and <dst_vpn> arguments.
    171172 * It does nothing if the source PTE is not MAPPED and SMALL.
    172173 * It optionnally activates the "Copy on Write" mechanism: when the <cow> argument is
    173174 * true: the GPT_WRITABLE flag is reset, and the GPT_COW flag is set.
    174  * A new second level PT2(s) is allocated for destination GPT if required.
     175 * A new second level PT2 is allocated for the destination GPT if required.
    175176 * It returns in the <ppn> and <mapped> arguments the PPN value for the copied PTE,
    176177 * and a boolean indicating if the PTE is mapped and small, and was actually copied.
    177178 ****************************************************************************************
    178  * @ dst_gpt      : [in]  local pointer on the local destination GPT.
    179  * @ src_gpt_xp   : [in]  extended pointer on the remote source GPT.
    180  * @ vpn_base     : [in]  vpn defining the PTE to be copied.
     179 * @ dst_gpt      : [in]  local pointer on local destination GPT.
     180 * @ dst_vpn      : [in]  vpn defining the PTE in the desination GPT.
     181 * @ src_gpt_xp   : [in]  extended pointer on remote source GPT.
     182 * @ src_vpn      : [in]  vpn defining the PTE in the source GPT.
    181183 * @ cow          : [in]  activate the COPY-On-Write mechanism if true.
    182184 * @ ppn          : [out] PPN value (only if mapped is true).
     
    185187 ***************************************************************************************/
    186188error_t hal_gpt_pte_copy( gpt_t    * dst_gpt,
     189                          vpn_t      dst_vpn,
    187190                          xptr_t     src_gpt_xp,
    188                           vpn_t      vpn,
     191                          vpn_t      src_vpn,
    189192                          bool_t     cow,
    190193                          ppn_t    * ppn,
  • trunk/hal/generic/hal_special.h

    r624 r625  
    101101 * This function returns the current value of stack pointer from core register.
    102102 ****************************************************************************************/
    103 uint32_t hal_get_sp( void );
    104 
    105 /*****************************************************************************************
    106  * This function returns the current value of the return adddress from core register.
    107  ****************************************************************************************/
    108 uint32_t hal_get_ra( void );
    109 
    110 /*****************************************************************************************
    111  * This function registers a new value in the core stack pointer and returns previous one.
    112  ****************************************************************************************/
    113 inline uint32_t hal_set_sp( void * new_val );
     103reg_t hal_get_sp( void );
    114104
    115105/*****************************************************************************************
    116106 * This function returns the faulty address in case of address exception.
    117107 ****************************************************************************************/
    118 uint32_t hal_get_bad_vaddr( void );
     108reg_t hal_get_bad_vaddr( void );
    119109
    120110/*****************************************************************************************
  • trunk/hal/generic/hal_vmm.h

    r623 r625  
    5959error_t hal_vmm_kernel_update( struct process_s * process );
    6060
     61/****************************************************************************************
     62 * Depending on the hardware architecture, this function displays the current state
     63 * of the VMM of the process identified by the <process> argument.
     64 * It displays all valit GPT entries when the <mapping> argument is true.
     65 ****************************************************************************************
     66 * @ process   : local pointer on user process descriptor.
     67 * @ return 0 if success / return ENOMEM if failure.
     68 ***************************************************************************************/
     69void hal_vmm_display( struct process_s * process,
     70                      bool_t             mapping );
     71
     72
     73
    6174#endif  /* HAL_VMM_H_ */
  • trunk/hal/tsar_mips32/core/hal_context.c

    r570 r625  
    152152    {
    153153        context->a0_04   = (uint32_t)thread->entry_args;
    154         context->sp_29   = (uint32_t)thread->u_stack_base + (uint32_t)thread->u_stack_size - 8;
     154        context->sp_29   = (uint32_t)thread->user_stack_vseg->max - 8;
    155155        context->ra_31   = (uint32_t)&hal_kentry_eret;
    156156        context->c0_epc  = (uint32_t)thread->entry_func;
     
    175175void hal_cpu_context_fork( xptr_t child_xp )
    176176{
    177     // allocate a local CPU context in kernel stack
    178     // It is initialized from local parent context
    179     // and from child specific values, and is copied in
    180     // in the remote child context using a remote_memcpy()
     177    // get pointer on calling thread
     178    thread_t * this = CURRENT_THREAD;
     179
     180    // allocate a local CPU context in parent kernel stack
    181181    hal_cpu_context_t  context;
    182182
    183     // get local parent thread local pointer
     183    // get local parent thread cluster and local pointer
     184    cxy_t      parent_cxy = local_cxy;
    184185    thread_t * parent_ptr = CURRENT_THREAD;
    185186
     
    188189    thread_t * child_ptr = GET_PTR( child_xp );
    189190
    190     // get remote child cpu_context local pointer
     191    // get local pointer on remote child cpu context
    191192    char * child_context_ptr = hal_remote_lpt( XPTR(child_cxy , &child_ptr->cpu_context) );
    192193
    193194    // get local pointer on remote child process
    194     process_t * process = (process_t *)hal_remote_lpt( XPTR(child_cxy , &child_ptr->process) );
     195    process_t * process = hal_remote_lpt( XPTR(child_cxy , &child_ptr->process) );
    195196
    196197    // get ppn of remote child process page table
    197     uint32_t    pt_ppn = hal_remote_l32( XPTR(child_cxy , &process->vmm.gpt.ppn) );
    198 
    199     // save CPU registers in local CPU context
     198    uint32_t pt_ppn = hal_remote_l32( XPTR(child_cxy , &process->vmm.gpt.ppn) );
     199
     200    // get local pointer on parent uzone from parent thread descriptor
     201    uint32_t * parent_uzone = parent_ptr->uzone_current;
     202
     203    // compute  local pointer on child uzone
     204    uint32_t * child_uzone  = (uint32_t *)( (intptr_t)parent_uzone +
     205                                            (intptr_t)child_ptr    -
     206                                            (intptr_t)parent_ptr  );
     207
     208    // update the uzone pointer in child thread descriptor
     209    hal_remote_spt( XPTR( child_cxy , &child_ptr->uzone_current ) , child_uzone );
     210
     211#if DEBUG_HAL_CONTEXT
     212uint32_t cycle = (uint32_t)hal_get_cycles();
     213if( DEBUG_HAL_CONTEXT < cycle )
     214printk("\n[%s] thread[%x,%x] parent_uzone %x / child_uzone %x / cycle %d\n",
     215__FUNCTION__, this->process->pid, this->trdid, parent_uzone, child_uzone, cycle );
     216#endif
     217
     218    // copy parent kernel stack to child thread descriptor
     219    // (this includes the uzone, that is allocated in the kernel stack)
     220    char * parent_ksp = (char *)hal_get_sp();
     221    char * child_ksp  = (char *)((intptr_t)parent_ksp +
     222                                 (intptr_t)child_ptr  -
     223                                 (intptr_t)parent_ptr );
     224
     225    uint32_t size = (uint32_t)parent_ptr + CONFIG_THREAD_DESC_SIZE - (uint32_t)parent_ksp;
     226
     227    hal_remote_memcpy( XPTR( child_cxy , child_ksp ),
     228                       XPTR( local_cxy , parent_ksp ),
     229                       size );
     230
     231#if DEBUG_HAL_CONTEXT
     232cycle = (uint32_t)hal_get_cycles();
     233printk("\n[%s] thread[%x,%x] copied kstack from parent %x to child %x / cycle %d\n",
     234__FUNCTION__, this->process->pid, this->trdid, parent_ptr, child_ptr, cycle );
     235#endif
     236
     237    // patch the user stack pointer slot in the child uzone[UZ_SP]
     238    // because parent and child use the same offset to access the user stack,
     239    // but parent and child do not have the same user stack base address.
     240    uint32_t parent_us_base = parent_ptr->user_stack_vseg->min;
     241    vseg_t * child_us_vseg  = hal_remote_lpt( XPTR( child_cxy , &child_ptr->user_stack_vseg ) );
     242    uint32_t child_us_base  = hal_remote_l32( XPTR( child_cxy , &child_us_vseg->min ) );
     243    uint32_t parent_usp     = parent_uzone[UZ_SP];
     244    uint32_t child_usp      = parent_usp + child_us_base - parent_us_base;
     245
     246    hal_remote_s32( XPTR( child_cxy , &child_uzone[UZ_SP] ) , child_usp );
     247
     248#if DEBUG_HAL_CONTEXT
     249cycle = (uint32_t)hal_get_cycles();
     250printk("\n[%s] thread[%x,%x] parent_usp %x / child_usp %x / cycle %d\n",
     251__FUNCTION__, this->process->pid, this->trdid, parent_usp, child_usp, cycle );
     252#endif
     253
     254    // save current values of CPU registers to local CPU context
    200255    hal_do_cpu_save( &context );
    201256
    202     // From this point, both parent and child threads execute the following code.
    203     // They can be distinguished by the CURRENT_THREAD value, and child will only
    204     // execute it when it is unblocked by parent, after return to sys_fork().
    205     // - parent thread copies user stack, and patch sp_29 / c0_th / C0_sr / c2_ptpr
    206     // - child thread does nothing
    207 
    208     thread_t * current = CURRENT_THREAD;
    209 
    210     if( current == parent_ptr )    // current == parent thread
     257    // From this point, both parent and child can execute the following code,
     258    // but child thread will only execute it after being unblocked by parent thread.
     259    // They can be distinguished by the (CURRENT_THREAD,local_cxy) values,
     260    // and we must re-initialise the calling thread pointer from c0_th register
     261
     262    this = CURRENT_THREAD;
     263
     264    if( (this == parent_ptr) && (local_cxy == parent_cxy) )   // parent thread
    211265    {
    212         // get parent and child stack pointers
    213         char * parent_sp = (char *)context.sp_29;
    214         char * child_sp  = (char *)((intptr_t)parent_sp +
    215                                     (intptr_t)child_ptr -
    216                                     (intptr_t)parent_ptr );
    217  
    218         // patch kernel_stack pointer, current thread, and status slots
    219         context.sp_29   = (uint32_t)child_sp;
     266        // patch 4 slots in the local CPU context: the sp_29 / c0_th / C0_sr / c2_ptpr
     267        // slots are not identical in parent and child
     268        context.sp_29   = context.sp_29 + (intptr_t)child_ptr - (intptr_t)parent_ptr;
    220269        context.c0_th   = (uint32_t)child_ptr;
    221270        context.c0_sr   = SR_SYS_MODE;
    222271        context.c2_ptpr = pt_ppn >> 1;
    223272
    224         // copy local context to remote child context)
     273        // copy this patched context to remote child context
    225274        hal_remote_memcpy( XPTR( child_cxy , child_context_ptr ),
    226275                           XPTR( local_cxy  , &context ) ,
    227276                           sizeof( hal_cpu_context_t ) );
    228 
    229         // copy kernel stack content from local parent thread to remote child thread
    230         uint32_t size = (uint32_t)parent_ptr + CONFIG_THREAD_DESC_SIZE - (uint32_t)parent_sp;
    231         hal_remote_memcpy( XPTR( child_cxy , child_sp ),
    232                            XPTR( local_cxy , parent_sp ),
    233                            size );
     277#if DEBUG_HAL_CONTEXT
     278cycle = (uint32_t)hal_get_cycles();
     279printk("\n[%s] thread[%x,%x] copied CPU context to child / cycle %d\n",
     280__FUNCTION__, this->process->pid, this->trdid, cycle );
     281#endif
     282
     283        // parent thread unblock child thread
     284        thread_unblock( XPTR( child_cxy , child_ptr ) , THREAD_BLOCKED_GLOBAL );
     285
     286#if DEBUG_HAL_CONTEXT
     287cycle = (uint32_t)hal_get_cycles();
     288printk("\n[%s] thread[%x,%x] unblocked child thread / cycle %d\n",
     289__FUNCTION__, this->process->pid, this->trdid, cycle );
     290#endif
     291
    234292    }
    235     else                           // current == child thread
    236     {
    237         assert( (current == child_ptr) , "current = %x / child = %x\n");
    238     }
     293
    239294}  // end hal_cpu_context_fork()
    240295
     
    285340void hal_cpu_context_destroy( thread_t * thread )
    286341{
    287     kmem_req_t  req;
    288 
    289     req.type = KMEM_CPU_CTX;
    290     req.ptr  = thread->cpu_context;
    291     kmem_free( &req );
     342    kmem_req_t          req;
     343
     344    hal_cpu_context_t * ctx = thread->cpu_context;
     345
     346    // release CPU context if required
     347    if( ctx != NULL )
     348    {   
     349        req.type = KMEM_CPU_CTX;
     350        req.ptr  = ctx;
     351        kmem_free( &req );
     352    }
    292353
    293354}  // end hal_cpu_context_destroy()
     
    348409    kmem_req_t  req;
    349410
    350     req.type = KMEM_FPU_CTX;
    351     req.ptr  = thread->fpu_context;
    352     kmem_free( &req );
     411    hal_fpu_context_t * context = thread->fpu_context;
     412
     413    // release FPU context if required
     414    if( context != NULL )
     415    {   
     416        req.type = KMEM_FPU_CTX;
     417        req.ptr  = context;
     418        kmem_free( &req );
     419    }
    353420
    354421}  // end hal_fpu_context_destroy()
  • trunk/hal/tsar_mips32/core/hal_exception.c

    r619 r625  
    189189    if( CURRENT_THREAD->type != THREAD_USER )
    190190    {
    191         printk("\n[KERNEL PANIC] in %s : illegal thread type %s\n",
     191        printk("\n[PANIC] in %s : illegal thread type %s\n",
    192192        __FUNCTION__, thread_type_str(CURRENT_THREAD->type) );
    193193
     
    250250            else if( error == EXCP_USER_ERROR )      // illegal vaddr
    251251            {
    252                 printk("\n[USER ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     252                printk("\n[ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
    253253                "  %s : epc %x / badvaddr %x / is_ins %d\n",
    254254                __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     
    260260            else  // error == EXCP_KERNEL_PANIC 
    261261            {
    262                 printk("\n[KERNEL PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     262                printk("\n[PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
    263263                "  %s : epc %x / badvaddr %x / is_ins %d\n",
    264264                __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     
    272272        case MMU_READ_PRIVILEGE_VIOLATION:   // illegal
    273273        {
    274             printk("\n[USER ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     274            printk("\n[ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
    275275            "  %s : epc %x / badvaddr %x / is_ins %d\n",
    276276            __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     
    299299            else if( error == EXCP_USER_ERROR )  // illegal write access
    300300            {
    301                     printk("\n[USER ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     301                    printk("\n[ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
    302302                    "  %s : epc %x / badvaddr %x / is_ins %d\n",
    303303                    __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     
    309309            else   // error == EXCP_KERNEL_PANIC
    310310            {
    311                 printk("\n[KERNEL PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     311                printk("\n[PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
    312312                "  %s : epc %x / badvaddr %x / is_ins %d\n",
    313313                __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     
    320320        case MMU_READ_EXEC_VIOLATION:        // user error
    321321        {
    322             printk("\n[USER ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     322            printk("\n[ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
    323323            "  %s : epc %x / badvaddr %x / is_ins %d\n",
    324324            __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     
    330330        default:                             // this is a kernel error   
    331331        {
    332             printk("\n[KERNEL PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     332            printk("\n[PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
    333333            "  %s : epc %x / badvaddr %x / is_ins %d\n",
    334334            __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     
    346346//////////////////////////////////////////////////////////////////////////////////////////
    347347// @ this     : pointer on faulty thread descriptor.
    348 // @ error    : EXCP_USER_ERROR or EXCP_KERNEL_PANIC
    349 //////////////////////////////////////////////////////////////////////////////////////////
    350 static void hal_exception_dump( thread_t * this,
    351                                 error_t    error )
     348//////////////////////////////////////////////////////////////////////////////////////////
     349static void hal_exception_dump( thread_t * this )
    352350{
    353351    core_t    * core    = this->core;
     
    366364    remote_busylock_acquire( lock_xp );
    367365
    368     if( error == EXCP_USER_ERROR )
    369     {
    370         nolock_printk("\n=== USER ERROR / thread(%x,%x) / core[%d] / cycle %d ===\n",
    371         process->pid, this->trdid, core->lid, (uint32_t)hal_get_cycles() );
    372     }
    373     else
    374     {
    375         nolock_printk("\n=== KERNEL PANIC / thread(%x,%x) / core[%d] / cycle %d ===\n",
    376         process->pid, this->trdid, core->lid, (uint32_t)hal_get_cycles() );
    377     }
     366    nolock_printk("\n=== thread(%x,%x) / core[%d] / cycle %d ===\n",
     367    process->pid, this->trdid, core->lid, (uint32_t)hal_get_cycles() );
    378368
    379369        nolock_printk("busylocks = %d / blocked_vector = %X / flags = %X\n\n",
     
    507497        if( error == EXCP_USER_ERROR )          //  user error => kill user process
    508498        {
    509         hal_exception_dump( this , error );
     499        hal_exception_dump( this );
    510500
    511501        sys_exit( EXIT_FAILURE );
     
    513503    else if( error == EXCP_KERNEL_PANIC )   // kernel error => kernel panic
    514504    {
    515         hal_exception_dump( this , error );
     505        hal_exception_dump( this );
    516506
    517507        hal_core_sleep();
  • trunk/hal/tsar_mips32/core/hal_gpt.c

    r624 r625  
    823823///////////////////////////////////////////
    824824error_t hal_gpt_pte_copy( gpt_t  * dst_gpt,
     825                          vpn_t    dst_vpn,
    825826                          xptr_t   src_gpt_xp,
    826                           vpn_t    vpn,
     827                          vpn_t    src_vpn,
    827828                          bool_t   cow,
    828829                          ppn_t  * ppn,
    829830                          bool_t * mapped )
    830831{
    831     uint32_t     ix1;       // index in PT1
    832     uint32_t     ix2;       // index in PT2
     832    uint32_t     src_ix1;   // index in SRC PT1
     833    uint32_t     src_ix2;   // index in SRC PT2
     834
     835    uint32_t     dst_ix1;   // index in DST PT1
     836    uint32_t     dst_ix2;   // index in DST PT2
    833837
    834838    cxy_t        src_cxy;   // SRC GPT cluster
     
    862866thread_t * this  = CURRENT_THREAD;
    863867if( DEBUG_HAL_GPT_COPY < cycle )
    864 printk("\n[%s] : thread[%x,%x] enter / vpn %x / src_cxy %x / dst_cxy %x / cycle %d\n",
    865 __FUNCTION__, this->process->pid, this->trdid, vpn, src_cxy, local_cxy, cycle );
     868printk("\n[%s] : thread[%x,%x] enter / src_cxy %x / dst_cxy %x / cycle %d\n",
     869__FUNCTION__, this->process->pid, this->trdid, src_cxy, local_cxy, cycle );
    866870#endif
    867871
     
    878882    assert( (dst_pt1 != NULL) , "dst_pt1 does not exist\n");
    879883
    880     ix1 = TSAR_MMU_IX1_FROM_VPN( vpn );
    881     ix2 = TSAR_MMU_IX2_FROM_VPN( vpn );
     884    // compute SRC indexes
     885    src_ix1 = TSAR_MMU_IX1_FROM_VPN( src_vpn );
     886    src_ix2 = TSAR_MMU_IX2_FROM_VPN( src_vpn );
     887
     888    // compute DST indexes
     889    dst_ix1 = TSAR_MMU_IX1_FROM_VPN( dst_vpn );
     890    dst_ix2 = TSAR_MMU_IX2_FROM_VPN( dst_vpn );
    882891
    883892    // get src_pte1
    884     src_pte1 = hal_remote_l32( XPTR( src_cxy , &src_pt1[ix1] ) );
     893    src_pte1 = hal_remote_l32( XPTR( src_cxy , &src_pt1[src_ix1] ) );
    885894
    886895    // do nothing if src_pte1 not MAPPED or not SMALL
     
    888897    {
    889898        // get dst_pt1 entry
    890         dst_pte1 = dst_pt1[ix1];
     899        dst_pte1 = dst_pt1[dst_ix1];
    891900
    892901        // map dst_pte1 if required
     
    915924
    916925            // register it in DST_GPT
    917             dst_pt1[ix1] = dst_pte1;
     926            dst_pt1[dst_ix1] = dst_pte1;
    918927        }
    919928
     
    927936
    928937        // get attr and ppn from SRC_PT2
    929         src_pte2_attr = hal_remote_l32( XPTR( src_cxy , &src_pt2[2 * ix2]     ) );
    930         src_pte2_ppn  = hal_remote_l32( XPTR( src_cxy , &src_pt2[2 * ix2 + 1] ) );
     938        src_pte2_attr = hal_remote_l32( XPTR( src_cxy , &src_pt2[2 * src_ix2]     ) );
     939        src_pte2_ppn  = hal_remote_l32( XPTR( src_cxy , &src_pt2[2 * src_ix2 + 1] ) );
    931940
    932941        // do nothing if src_pte2 not MAPPED
     
    934943        {
    935944            // set PPN in DST PTE2
    936             dst_pt2[2*ix2+1] = src_pte2_ppn;
     945            dst_pt2[2 * dst_ix2 + 1] = src_pte2_ppn;
    937946                       
    938947            // set attributes in DST PTE2         
    939948            if( cow && (src_pte2_attr & TSAR_MMU_WRITABLE) )
    940949            {
    941                 dst_pt2[2*ix2] = (src_pte2_attr | TSAR_MMU_COW) & (~TSAR_MMU_WRITABLE);
     950                dst_pt2[2 * dst_ix2] = (src_pte2_attr | TSAR_MMU_COW) & (~TSAR_MMU_WRITABLE);
    942951            }
    943952            else
    944953            {
    945                 dst_pt2[2*ix2] = src_pte2_attr;
     954                dst_pt2[2 * dst_ix2] = src_pte2_attr;
    946955            }
    947956
     
    953962cycle = (uint32_t)hal_get_cycles;
    954963if( DEBUG_HAL_GPT_COPY < cycle )
    955 printk("\n[%s] : thread[%x,%x] exit / copy done for vpn %x / cycle %d\n",
    956 __FUNCTION__, this->process->pid, this->trdid, vpn, cycle );
     964printk("\n[%s] : thread[%x,%x] exit / copy done for src_vpn %x / dst_vpn %x / cycle %d\n",
     965__FUNCTION__, this->process->pid, this->trdid, src_vpn, dst_vpn, cycle );
    957966#endif
    958967
     
    970979cycle = (uint32_t)hal_get_cycles;
    971980if( DEBUG_HAL_GPT_COPY < cycle )
    972 printk("\n[%s] : thread[%x,%x] exit / nothing done for vpn %x / cycle %d\n",
    973 __FUNCTION__, this->process->pid, this->trdid, vpn, cycle );
     981printk("\n[%s] : thread[%x,%x] exit / nothing done / cycle %d\n",
     982__FUNCTION__, this->process->pid, this->trdid, cycle );
    974983#endif
    975984
  • trunk/hal/tsar_mips32/core/hal_kentry.S

    r438 r625  
    44 * AUthors   Ghassan Almaless (2007,2008,2009,2010,2011,2012)
    55 *           Mohamed Lamine Karaoui (2015)
    6  *           Alain Greiner (2017)
     6 *           Alain Greiner (2016,2017,2018,2019)
    77 *
    88 * Copyright (c) UPMC Sorbonne Universites
     
    8787#------------------------------------------------------------------------------------
    8888# Kernel Entry point for Interrupt / Exception / Syscall
    89 # The c2_dext and c2_iext CP2 registers must have been previously set
    90 # to "local_cxy", because the kernel run with MMU desactivated.
     89# The c2_dext CP2 register must have been previously set
     90# to "local_cxy", because the kernel run with data MMU desactivated.
    9191#------------------------------------------------------------------------------------
    9292
     
    9696        andi    $26,    $26,  0x10          # test User Mode bit
    9797        beq     $26,    $0,       kernel_mode   # jump if core already in kernel
    98         ori     $27,    $0,       0x3           # $27 <= code for MMU OFF
     98        ori     $27,    $0,       0xB           # $27 <= code data MMU OFF
    9999       
    100100#------------------------------------------------------------------------------------
     
    102102# to handle a syscall, an interrupt, or an user exception.
    103103# - save current c2_mode in $26.
    104 # - set MMU OFF.
     104# - set data MMU OFF.
    105105# - copy user stack pointer in $27 to be saved in uzone.
    106 # - set kernel stack pointer in $29 == top_kernel_stack(this).
     106# - set kernel stack pointer in $29 (kernel stack empty at firts entry).
    107107
    108108user_mode:
    109109
    110110    mfc2    $26,    $1                  # $26 <= c2_mode
    111         mtc2    $27,    $1                              # set MMU OFF
     111        mtc2    $27,    $1                              # set data MMU OFF
    112112    move    $27,    $29                 # $27 <= user stack pointer
    113113        mfc0    $29,    $4,   2             # get pointer on thread descriptor from c0_th
     
    121121# after a syscall, to handle an interrupt, or to handle a non-fatal exception.
    122122# - save current c2_mode in $26.
    123 # - set MMU OFF.
     123# - set data MMU OFF.
    124124# - copy current kernel stack pointer in $27.
    125125
     
    127127
    128128    mfc2    $26,    $1                  # $26 <= c2_mode
    129         mtc2    $27,    $1                              # set MMU OFF
     129        mtc2    $27,    $1                              # set data MMU OFF
    130130    move    $27,    $29                 # $27 <= current kernel stack pointer
    131131
     
    133133# This code is executed in both modes (user or kernel):
    134134# The assumptions are:
    135 # - c2_mode contains the MMU OFF value.
     135# - c2_mode contains the data MMU OFF value.
    136136# - $26 contains the previous c2_mode value.
    137137# - $27 contains the previous sp value (can be usp or ksp).
     
    139139# We execute the following actions:
    140140# - decrement $29 to allocate an uzone in kernel stack
    141 # - save relevant GPR, CP0 and CP2 registers to uzone.
    142 # - set the SR in kernel mode: IRQ disabled, clear exl.
     141# - save GPR, CP0 and CP2 registers to uzone.
     142# - set the SR in kernel mode: IRQ disabled, clear EXL.
    143143
    144144unified_mode:
     
    195195    sw      $26,    (UZ_MODE*4)($29)    # save previous c2_mode (can be user or kernel)
    196196
    197     mfc0    $3,     $12
     197    mfc0    $3,     $12                 # $3 <= c0_sr
    198198        srl         $3,     $3,   5
    199199        sll     $3,         $3,   5                 # reset 5 LSB bits
     
    216216    nop
    217217    move    $4,     $2
     218    jal     putd
     219    nop
     220    la      $4,     msg_crlf
     221    jal     puts
     222    nop   
     223    # display saved CR value
     224    la      $4,     msg_cr
     225    jal     puts
     226    nop
     227    lw      $4,         (UZ_CR*4)($29)
    218228    jal     putx
    219229    nop
     
    286296   
    287297#------------------------------------------------------------------------------------
    288 # This code handle the uzone pointers stack, and calls the relevant
     298# This code handle the two-slots uzone pointers stack, and calls the relevant
    289299# Interrupt / Exception / Syscall handler, depending on XCODE in CP0_CR.
    290300# Both the hal_do_syscall() and the hal_do_exception() functions use
     
    338348# - All registers saved in the uzone are restored, using the pointer on uzone,
    339349#   that is contained in $29.
    340 # - The "uzone" field in thread descriptor, that has beeen modified at kernel entry
    341 #   is restored from value contained in the uzone[UZ_SP] slot.
     350# - The "current_uzone" pointer in thread descriptor, that has beeen modified at
     351#   kernel entry is restored from value contained in the uzone[UZ_SP] slot.
    342352# -----------------------------------------------------------------------------------
    343353
     
    365375    nop
    366376    move    $4,     $2
     377    jal     putd
     378    nop
     379    la      $4,     msg_crlf
     380    jal     puts
     381    nop   
     382    # display saved CR value
     383    la      $4,     msg_cr
     384    jal     puts
     385    nop
     386    lw      $4,         (UZ_CR*4)($29)
    367387    jal     putx
    368388    nop
     
    479499
    480500        lw          $26,    (UZ_MODE*4)($27)   
    481     mtc2    $26,    $1                  # restore CP2_MODE from uzone
     501    mtc2    $26,    $1                  # restore c2_mode from uzone
    482502
    483503# -----------------------------------------------------------------------------------
     
    494514    .section .kdata
    495515
     516msg_cr:
     517    .align 2
     518    .asciiz "- UZ_CR   = "
    496519msg_sp:
    497520    .align 2
  • trunk/hal/tsar_mips32/core/hal_kentry.h

    r481 r625  
    11/*
    2  * hal_kentry.h - MIPS32 registers mnemonics
     2 * hal_kentry.h - uzone definition
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Author     Alain Greiner (2016,2017,2018,2019)
     5 *
     6 * Copyright (c) UPMC Sorbonne Universites
    67 *
    7  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    89 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    2829// a fixed size array of 32 bits integers, used by the kentry function to save/restore
    2930// the MIPS32 CPU registers, at each exception / interruption / syscall.
    30 // It also defines several initial values for the SR register.
    3131//
    3232// This file is included in the hal_kentry.S, hal_syscall.c, hal_exception.c,
     
    3636
    3737/****************************************************************************************
    38  * This structure defines the cpu_uzone dynamically allocated in the kernel stack
    39  * by the hal_kentry assembly code for the TSAR_MIPS32 architecture.
     38 * This structure defines the "uzone" dynamically allocated in the kernel stack
     39 * by the hal_kentry assembly code to save the MIPS32 registers each time a core
     40 * enters the kernel to handle an interrupt, exception, or syscall.
     41 * These define are specific for the TSAR_MIPS32 architecture.
     42 *
    4043 * WARNING : It is replicated in hal_kentry.S file.
    4144 ***************************************************************************************/
     
    8790 * The hal_kentry_enter() function is the unique kernel entry point in case of
    8891 * exception, interrupt, or syscall for the TSAR_MIPS32 architecture. 
    89  * It can be executed by a core in user mode (in case of exception or syscall),
    90  * or by a core already in kernel mode (in case of interrupt).
    91  *
     92 * It can be executed by a core in user mode or by a core already in kernel mode
     93 * (in case of interrupt or non fatal exception).
    9294 * In both cases it allocates an "uzone" space in the kernel stack to save the
    9395 * CPU registers values, desactivates the MMU, and calls the relevant handler
     
    9597 *
    9698 * After handler execution, it restores the CPU context from the uzone and jumps
    97  * to address contained in EPC calling hal_kentry_eret()
     99 * to address contained in EPC calling the hal_kentry_eret() function.
    98100 ************************************************************************************/
    99101void hal_kentry_enter( void );
     
    101103/*************************************************************************************
    102104 * The hal_kentry_eret() function contains only the assembly "eret" instruction,
    103  * that reset the EXL bit in the c0_sr register, and jump to the address
     105 * that reset the EXL bit in the c0_sr register, and jumps to the address
    104106 * contained in the c0_epc register.
    105107 * ************************************************************************************/
  • trunk/hal/tsar_mips32/core/hal_remote.c

    r610 r625  
    381381    uint32_t scxy = (uint32_t)GET_CXY( src );
    382382
    383 /*
    384 if( local_cxy == 1 )
    385 printk("\n@@@ %s : scxy %x / sptr %x / dcxy %x / dptr %x\n",
    386 __FUNCTION__, scxy, sptr, dcxy, dptr );
    387 */
    388383    hal_disable_irq( &save_sr );
    389384
  • trunk/hal/tsar_mips32/core/hal_special.c

    r624 r625  
    4040extern cxy_t local_cxy;
    4141extern void  hal_kentry_enter( void );
     42
     43////////////////////////////////////////////////////////////////////////////////
     44// For the TSAR architecture, this function registers the address of the
     45// hal_kentry_enter() function in the MIPS32 cp0_ebase register.
     46////////////////////////////////////////////////////////////////////////////////
     47void hal_set_kentry( void )
     48{
     49    uint32_t kentry = (uint32_t)(&hal_kentry_enter);
     50
     51    asm volatile("mtc0   %0,  $15,  1" : : "r" (kentry) );
     52}
    4253
    4354/////////////////////////////////////////////////////////////////////////////////
     
    4859void hal_mmu_init( gpt_t * gpt )
    4960{
    50 
    51     // set PT1 base address in mmu_ptpr register
     61    // set PT1 base address in cp2_ptpr register
    5262    uint32_t ptpr = (((uint32_t)gpt->ptr) >> 13) | (local_cxy << 19);
    5363    asm volatile ( "mtc2   %0,   $0         \n" : : "r" (ptpr) );
    5464
    55     // set ITLB | ICACHE | DCACHE bits in mmu_mode register
     65    // set ITLB | ICACHE | DCACHE bits in cp2_mode register
    5666    asm volatile ( "ori    $26,  $0,  0xB   \n"
    5767                   "mtc2   $26,  $1         \n" );
     
    5969
    6070////////////////////////////////////////////////////////////////////////////////
    61 // For the TSAR architecture, this function registers the address of the
    62 // hal_kentry_enter() function in the MIPS32 cp0_ebase register.
    63 ////////////////////////////////////////////////////////////////////////////////
    64 void hal_set_kentry( void )
    65 {
    66     uint32_t kentry = (uint32_t)(&hal_kentry_enter);
    67 
    68     asm volatile("mtc0   %0,  $15,  1" : : "r" (kentry) );
    69 }
    70 
    71 ////////////////////////////////
     71// For the TSAR architecture, this function returns the current value
     72// of the 32 bits c0_sr register
     73////////////////////////////////////////////////////////////////////////////////
     74inline reg_t hal_get_sr( void )
     75{
     76    reg_t sr;
     77
     78        asm volatile ("mfc0    %0,    $12" : "=&r" (sr));
     79
     80        return sr;
     81}
     82
     83////////////////////////////////////////////////////////////////////////////////
     84// For the TSAR architecture, this function returns the 10 LSB bits
     85// of the 32 bits c0_ebase register : Y (4 bits) | Y (4 bits) | LID (2 bits)
     86////////////////////////////////////////////////////////////////////////////////
    7287inline gid_t hal_get_gid( void )
    7388{
     
    7994}
    8095
    81 ///////////////////////////////////
     96////////////////////////////////////////////////////////////////////////////////
     97// For the TSAR architecture, this function returns the current value
     98// of the 32 bits c0_count cycle counter.
     99////////////////////////////////////////////////////////////////////////////////
    82100inline reg_t hal_time_stamp( void )
    83101{
     
    87105
    88106    return count;
    89 }
    90 
    91 ///////////////////////////////
    92 inline reg_t hal_get_sr( void )
    93 {
    94     reg_t sr;
    95 
    96         asm volatile ("mfc0    %0,    $12" : "=&r" (sr));
    97 
    98         return sr;
    99107}
    100108
     
    131139}
    132140
    133 ///////////////////////////////////////////////////////
     141////////////////////////////////////////////////////////////////////////////////
     142// For the TSAR architecture, this function returns the current value
     143// of the 32 bits c0_th register.
     144////////////////////////////////////////////////////////////////////////////////
    134145inline struct thread_s * hal_get_current_thread( void )
    135146{
     
    141152}
    142153
    143 ///////////////////////////////////////////////////////
     154////////////////////////////////////////////////////////////////////////////////
     155// For the TSAR architecture, this function set a new value
     156// to the 32 bits c0_th register.
     157////////////////////////////////////////////////////////////////////////////////
    144158void hal_set_current_thread( struct thread_s * thread )
    145159{
     
    182196}
    183197
    184 ///////////////////////////
    185 uint32_t hal_get_sp( void )
     198////////////////////////////////////////////////////////////////////////////////
     199// For the TSAR architecture, this function returns the current value
     200// of the 32 bits sp_29 register.
     201////////////////////////////////////////////////////////////////////////////////
     202reg_t hal_get_sp( void )
    186203{
    187204        register uint32_t sp;
     
    190207 
    191208        return sp;
    192 }
    193 
    194 /////////////////////////////////////
    195 uint32_t hal_set_sp( void * new_val )
    196 {
    197         register uint32_t sp;
    198  
    199         asm volatile
    200         ( "or    %0,   $0,      $29   \n"
    201           "or    $29,  $0,      %1    \n"
    202           : "=&r" (sp) : "r" (new_val)  );
    203  
    204         return sp;
    205 }
    206 
    207 ///////////////////////////
    208 uint32_t hal_get_ra( void )
    209 {
    210         register uint32_t ra;
    211  
    212         asm volatile ("or    %0,   $0,   $31" : "=&r" (ra));
    213  
    214         return ra;
    215209}
    216210
  • trunk/hal/tsar_mips32/core/hal_switch.S

    r457 r625  
    22 * hal_witch.S - CPU context switch function for TSAR-MIPS32
    33 *
    4  * Author  Alain Greiner    (2016)
     4 * Author  Alain Greiner    (2016,2017,2018,2019)
    55 *
    66 * Copyright (c)  UPMC Sorbonne Universites
  • trunk/hal/tsar_mips32/core/hal_syscall.c

    r481 r625  
    2929#include <hal_kentry.h>
    3030
    31 /////////////////////
     31///////////////////////////
    3232void hal_do_syscall( void )
    3333{
     
    6363                         service_num );
    6464
    65     // get pointer on exit_thread uzone, because
    66     // exit_thread can be different from enter_thread
     65    // get pointer on exit_thread uzone, because exit thread
     66    // can be different from enter_thread for a fork syscall
    6767    this       = CURRENT_THREAD;
    6868    exit_uzone = (uint32_t *)this->uzone_current;
  • trunk/hal/tsar_mips32/core/hal_uspace.c

    r610 r625  
    249249        ".set noreorder             \n"
    250250        "move   $13,   %1           \n"   /* $13 <= str                     */
    251         "mfc2   $15,   $1           \n"   /* $15 <= DTLB and ITLB off       */
     251        "mfc2   $15,   $1           \n"   /* $15 <= MMU_MODE (DTLB off)     */
    252252        "ori    $14,   $15,  0x4    \n"   /* $14 <= mode DTLB on            */
    253253        "1:                         \n"
    254254        "mtc2   $14,   $1                       \n"   /* set DTLB on                    */
    255         "lb         $12,   0($13)       \n"   /* read char from user space      */
     255        "lb         $12,   0($13)       \n"   /* $12 <= one byte from u_space   */
    256256        "mtc2   $15,   $1                       \n"   /* set DTLB off                   */
    257257        "addi   $13,   $13,  1      \n"   /* increment address              */
  • trunk/hal/tsar_mips32/core/hal_vmm.c

    r624 r625  
    4848// This function is called by the process_zero_init() function during kernel_init.
    4949// It initializes the VMM of the kernel proces_zero (containing all kernel threads)
    50 // in the local cluster: it registers one "kcode" vseg in kernel VSL, and registers
    51 // one big page in slot[0] of kernel GPT.
     50// in the local cluster: For TSAR, it registers one "kcode" vseg in kernel VSL,
     51// and registers one big page in slot[0] of kernel GPT.
    5252//////////////////////////////////////////////////////////////////////////////////////////
    5353error_t  hal_vmm_kernel_init( boot_info_t * info )
     
    119119    return 0;
    120120
    121 }  // end hal_kernel_vmm_init()
    122 
    123 //////////////////////////////////////////////////////////////////////////////////////////
    124 // This function is called by the vmm_init() function to update the VMM of an user
    125 // process identified by the <process> argument.
    126 // It registers in the user VSL the "kcode" vseg, registered in the local kernel VSL,
    127 // and register in the user GPT the big page[0] mapped in the local kernel GPT.
     121}  // end hal_vmm_kernel_init()
     122
     123//////////////////////////////////////////////////////////////////////////////////////////
     124// This function registers in the VMM of an user process identified by the <process>
     125// argument all required kernel vsegs.
     126// For TSAR, it registers in the user VSL the "kcode" vseg, from the local kernel VSL,
     127// and register in the user GPT the big page[0] from the local kernel GPT.
    128128//////////////////////////////////////////////////////////////////////////////////////////
    129129error_t hal_vmm_kernel_update( process_t * process )
    130130{
    131     error_t error;
     131    error_t  error;
    132132    uint32_t attr;
    133133    uint32_t ppn;
    134134
     135    // get cluster identifier
     136    cxy_t cxy = local_cxy;
     137
    135138#if DEBUG_HAL_VMM
    136139thread_t * this = CURRENT_THREAD;
    137140printk("\n[%s] thread[%x,%x] enter in cluster %x \n",
    138 __FUNCTION__, this->process->pid, this->trdid, local_cxy );
     141__FUNCTION__, this->process->pid, this->trdid, cxy );
     142hal_vmm_display( &process_zero , true );
    139143hal_vmm_display( process , true );
    140 hal_vmm_display( &process_zero , true );
    141 #endif
    142 
    143     // get cluster identifier
    144     cxy_t cxy = local_cxy;
    145 
    146     // get extended pointer on kernel GPT
     144#endif
     145
     146    // get extended pointer on local kernel GPT
    147147    xptr_t k_gpt_xp = XPTR( cxy , &process_zero.vmm.gpt );
    148148
     
    212212                      bool_t      mapping )
    213213{
     214    // get pointer on process VMM
    214215    vmm_t * vmm = &process->vmm;
    215     gpt_t * gpt = &vmm->gpt;
    216216
    217217    // get pointers on TXT0 chdev
     
    220220    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
    221221
    222     // get extended pointer on remote TXT0 lock
    223     xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
    224 
    225     // get locks protecting the VSL and the GPT
    226     remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->vsegs_lock ) );
    227     remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->gpt_lock ) );
    228 
    229     // get TXT0 lock
    230     remote_busylock_acquire( lock_xp );
    231 
    232     nolock_printk("\n***** VSL and GPT for process %x in cluster %x\n",
    233     process->pid , local_cxy );
    234 
    235     // scan the list of vsegs
    236     xptr_t         root_xp = XPTR( local_cxy , &vmm->vsegs_root );
    237     xptr_t         iter_xp;
    238     xptr_t         vseg_xp;
    239     vseg_t       * vseg;
    240     XLIST_FOREACH( root_xp , iter_xp )
    241     {
    242         vseg_xp = XLIST_ELEMENT( iter_xp , vseg_t , xlist );
    243         vseg    = GET_PTR( vseg_xp );
    244 
    245         nolock_printk(" - %s : base = %X / size = %X / npages = %d\n",
    246         vseg_type_str( vseg->type ) , vseg->min , vseg->max - vseg->min , vseg->vpn_size );
    247 
    248         if( mapping )
     222    // build extended pointers on TXT0 lock, GPT lock and VSL lock
     223    xptr_t  txt_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
     224    xptr_t  vsl_lock_xp = XPTR( local_cxy , &vmm->vsl_lock );
     225    xptr_t  gpt_lock_xp = XPTR( local_cxy , &vmm->gpt_lock );
     226
     227    // get root of vsegs list
     228    xptr_t root_xp = XPTR( local_cxy , &vmm->vsegs_root );
     229
     230    // get the locks protecting TXT0, VSL, and GPT
     231    remote_rwlock_rd_acquire( vsl_lock_xp );
     232    remote_rwlock_rd_acquire( gpt_lock_xp );
     233    remote_busylock_acquire( txt_lock_xp );
     234
     235    nolock_printk("\n***** VSL and GPT for process %x in cluster %x / PT1 = %x\n",
     236    process->pid , local_cxy , vmm->gpt.ptr );
     237
     238    if( xlist_is_empty( root_xp ) )
     239    {
     240        nolock_printk("   ... no vsegs registered\n");
     241    }
     242    else  // scan the list of vsegs
     243    {
     244        xptr_t         iter_xp;
     245        xptr_t         vseg_xp;
     246        vseg_t       * vseg;
     247
     248        XLIST_FOREACH( root_xp , iter_xp )
    249249        {
    250             vpn_t    vpn     = vseg->vpn_base;
    251             vpn_t    vpn_max = vpn + vseg->vpn_size;
    252             ppn_t    ppn;
    253             uint32_t attr;
    254 
    255             while( vpn < vpn_max )
     250            vseg_xp = XLIST_ELEMENT( iter_xp , vseg_t , xlist );
     251            vseg    = GET_PTR( vseg_xp );
     252
     253            nolock_printk(" - %s : base = %X / size = %X / npages = %d\n",
     254            vseg_type_str(vseg->type), vseg->min, vseg->max - vseg->min, vseg->vpn_size );
     255
     256            if( mapping ) 
    256257            {
    257                 hal_gpt_get_pte( XPTR( local_cxy , gpt ) , vpn , &attr , &ppn );
    258 
    259                 if( attr & GPT_MAPPED )
     258                vpn_t    vpn     = vseg->vpn_base;
     259                vpn_t    vpn_max = vpn + vseg->vpn_size;
     260                ppn_t    ppn;
     261                uint32_t attr;
     262
     263                while( vpn < vpn_max )   // scan the PTEs
    260264                {
    261                     if( attr & GPT_SMALL )
     265                    hal_gpt_get_pte( XPTR( local_cxy , &vmm->gpt ) , vpn , &attr , &ppn );
     266
     267                    if( attr & GPT_MAPPED )
    262268                    {
    263                         nolock_printk("    . SMALL : vpn = %X / attr = %X / ppn = %X\n",
    264                         vpn , attr , ppn );
    265                         vpn++;
     269                        if( attr & GPT_SMALL )
     270                        {
     271                            nolock_printk("    . SMALL : vpn = %X / attr = %X / ppn = %X\n",
     272                            vpn , attr , ppn );
     273                            vpn++;
     274                        }
     275                        else
     276                        {
     277                            nolock_printk("    . BIG   : vpn = %X / attr = %X / ppn = %X\n",
     278                            vpn , attr , ppn );
     279                            vpn += 512;
     280                        }
    266281                    }
    267282                    else
    268283                    {
    269                         nolock_printk("    . BIG   : vpn = %X / attr = %X / ppn = %X\n",
    270                         vpn , attr , ppn );
    271                         vpn += 512;
     284                        vpn++;
    272285                    }
    273                 }
    274                 else
    275                 {
    276                     vpn++;
    277286                }
    278287            }
     
    280289    }
    281290
    282     // release TXT0 lock
    283     remote_busylock_release( lock_xp );
    284 
    285     // release the VSK and GPT locks
    286     remote_rwlock_rd_release( XPTR( local_cxy , &vmm->vsegs_lock ) );
    287     remote_rwlock_rd_release( XPTR( local_cxy , &vmm->gpt_lock ) );
     291    // release locks
     292    remote_busylock_release( txt_lock_xp );
     293    remote_rwlock_rd_release( gpt_lock_xp );
     294    remote_rwlock_rd_release( vsl_lock_xp );
    288295
    289296}  // hal_vmm_display()
  • trunk/hal/tsar_mips32/drivers/soclib_tty.c

    r619 r625  
    346346                owner_pid = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->pid ) );
    347347
    348                 // block TXT owner process only if it is not the INIT process
    349                 if( owner_pid != 1 )
    350                 {
    351                     // get parent process descriptor pointers
    352                     parent_xp  = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->parent_xp ) );
    353                     parent_cxy = GET_CXY( parent_xp );
    354                     parent_ptr = GET_PTR( parent_xp );
    355 
    356                     // get pointers on the parent process main thread
    357                     parent_main_ptr = hal_remote_lpt(XPTR(parent_cxy,&parent_ptr->th_tbl[0]));
    358                     parent_main_xp  = XPTR( parent_cxy , parent_main_ptr );
    359 
    360                     // transfer TXT ownership
    361                     process_txt_transfer_ownership( owner_xp );
    362 
    363                     // block all threads in all clusters, but the main thread
    364                     process_sigaction( owner_pid , BLOCK_ALL_THREADS );
    365 
    366                     // block the main thread
    367                     xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );
    368                     thread_block( main_xp , THREAD_BLOCKED_GLOBAL );
    369 
    370                     // atomically update owner process termination state
    371                     hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
    372                                           PROCESS_TERM_STOP );
    373 
    374                     // unblock the parent process main thread
    375                     thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
    376 
    377                     return;
    378                 }
     348// TXT owner cannot be the INIT process
     349assert( (owner_pid != 1) , "INIT process cannot be the TXT owner" );
     350
     351                // get parent process descriptor pointers
     352                parent_xp  = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->parent_xp ) );
     353                parent_cxy = GET_CXY( parent_xp );
     354                parent_ptr = GET_PTR( parent_xp );
     355
     356                // get pointers on the parent process main thread
     357                parent_main_ptr = hal_remote_lpt(XPTR(parent_cxy,&parent_ptr->th_tbl[0]));
     358                parent_main_xp  = XPTR( parent_cxy , parent_main_ptr );
     359
     360                // transfer TXT ownership
     361                process_txt_transfer_ownership( owner_xp );
     362
     363                // mark for block all threads in all clusters, but the main
     364                process_sigaction( owner_pid , BLOCK_ALL_THREADS );
     365
     366                // block the main thread
     367                xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );
     368                thread_block( main_xp , THREAD_BLOCKED_GLOBAL );
     369
     370                // atomically update owner process termination state
     371                hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
     372                                      PROCESS_TERM_STOP );
     373
     374                // unblock the parent process main thread
     375                thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
     376
     377                return;
    379378            }
    380379
     
    390389                owner_xp  = process_txt_get_owner( channel );
    391390
    392                 // check process exist
    393                 assert( (owner_xp != XPTR_NULL) ,
    394                 "TXT owner process not found\n" );
     391// check process exist
     392assert( (owner_xp != XPTR_NULL) , "TXT owner process not found\n" );
    395393
    396394                // get relevant infos on TXT owner process
     
    399397                owner_pid = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->pid ) );
    400398
    401                 // kill TXT owner process only if it is not the INIT process
    402                 if( owner_pid != 1 )
    403                 {
    404                     // get parent process descriptor pointers
    405                     parent_xp  = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->parent_xp ) );
    406                     parent_cxy = GET_CXY( parent_xp );
    407                     parent_ptr = GET_PTR( parent_xp );
    408 
    409                     // get pointers on the parent process main thread
    410                     parent_main_ptr = hal_remote_lpt(XPTR(parent_cxy,&parent_ptr->th_tbl[0]));
    411                     parent_main_xp  = XPTR( parent_cxy , parent_main_ptr );
    412 
    413                     // remove process from TXT list
    414                     process_txt_detach( owner_xp );
    415 
    416                     // mark for delete all thread in all clusters, but the main
    417                     process_sigaction( owner_pid , DELETE_ALL_THREADS );
     399// TXT owner cannot be the INIT process
     400assert( (owner_pid != 1) , "INIT process cannot be the TXT owner" );
     401
     402#if DEBUG_HAL_TXT_RX
     403if( DEBUG_HAL_TXT_RX < rx_cycle )
     404printk("\n[%s] TXT%d owner is process %x\n",
     405__FUNCTION__, channel, owner_pid );
     406#endif
     407                // get parent process descriptor pointers
     408                parent_xp  = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->parent_xp ) );
     409                parent_cxy = GET_CXY( parent_xp );
     410                parent_ptr = GET_PTR( parent_xp );
     411
     412                // get pointers on the parent process main thread
     413                parent_main_ptr = hal_remote_lpt(XPTR(parent_cxy,&parent_ptr->th_tbl[0]));
     414                parent_main_xp  = XPTR( parent_cxy , parent_main_ptr );
     415
     416                // transfer TXT ownership
     417                process_txt_transfer_ownership( owner_xp );
     418
     419                // remove process from TXT list
     420                // process_txt_detach( owner_xp );
     421
     422                // mark for delete all thread in all clusters, but the main
     423                process_sigaction( owner_pid , DELETE_ALL_THREADS );
    418424               
    419                     // block main thread
    420                     xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );
    421                     thread_block( main_xp , THREAD_BLOCKED_GLOBAL );
    422 
    423                     // atomically update owner process termination state
    424                     hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
    425                                           PROCESS_TERM_KILL );
    426 
    427                     // unblock the parent process main thread
    428                     thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
    429 
    430                     return;
    431                 }
     425#if DEBUG_HAL_TXT_RX
     426if( DEBUG_HAL_TXT_RX < rx_cycle )
     427printk("\n[%s] marked for delete all threads of process but main\n",
     428__FUNCTION__, owner_pid );
     429#endif
     430                // block main thread
     431                xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );
     432                thread_block( main_xp , THREAD_BLOCKED_GLOBAL );
     433
     434#if DEBUG_HAL_TXT_RX
     435if( DEBUG_HAL_TXT_RX < rx_cycle )
     436printk("\n[%s] blocked process %x main thread\n",
     437__FUNCTION__, owner_pid );
     438#endif
     439
     440                // atomically update owner process termination state
     441                hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
     442                                      PROCESS_TERM_KILL );
     443
     444                // unblock the parent process main thread
     445                thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
     446
     447#if DEBUG_HAL_TXT_RX
     448if( DEBUG_HAL_TXT_RX < rx_cycle )
     449printk("\n[%s] unblocked parent process %x main thread\n",
     450__FUNCTION__, hal_remote_l32( XPTR( parent_cxy , &parent_ptr->pid) ) );
     451#endif
     452                return;
    432453            }
    433454
Note: See TracChangeset for help on using the changeset viewer.