Ignore:
Timestamp:
Dec 5, 2017, 4:20:07 PM (6 years ago)
Author:
alain
Message:

Fix several bugs in the fork() syscall.

Location:
trunk/hal/tsar_mips32/core
Files:
9 edited

Legend:

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

    r407 r408  
    3636
    3737/////////////////////////////////////////////////////////////////////////////////////////
    38 //       Define various SR values for TSAR-MIPS32
    39 /////////////////////////////////////////////////////////////////////////////////////////
    40 
    41 #define SR_USR_MODE       0x0000FC13
    42 #define SR_USR_MODE_FPU   0x2000FC13
    43 #define SR_SYS_MODE       0x0000FC00
     38//       Define various SR initialisation values for TSAR-MIPS32
     39/////////////////////////////////////////////////////////////////////////////////////////
     40
     41#define SR_USR_MODE       0x0000FF13
     42#define SR_USR_MODE_FPU   0x2000FF13
     43#define SR_SYS_MODE       0x0000FF00
    4444
    4545/////////////////////////////////////////////////////////////////////////////////////////
     
    191191}  // end hal_cpu_context_create()
    192192
     193////////////////////////////////////////////
     194void hal_cpu_context_fork( xptr_t child_xp )
     195{
     196    // allocate a local CPU context in kernel stack
     197    // It is initialized from local parent context
     198    // and from child specific values, and is copied in
     199    // in the remote child context using a remote_memcpy()
     200    hal_cpu_context_t  context;
     201
     202    // get local parent thread local pointer
     203    thread_t * parent_ptr = CURRENT_THREAD;
     204
     205    // get remote child thread cluster and local pointer
     206    cxy_t      child_cxy = GET_CXY( child_xp );
     207    thread_t * child_ptr = (thread_t *)GET_PTR( child_xp );
     208
     209    // get remote child cpu_context local pointer
     210    char * child_context_ptr = hal_remote_lpt( XPTR(child_cxy , &child_ptr->cpu_context) );
     211
     212    // get local pointer on remote child process
     213    process_t * process = (process_t *)hal_remote_lpt( XPTR(child_cxy , &child_ptr->process) );
     214
     215    // get ppn of remote child process page table
     216    uint32_t    pt_ppn = hal_remote_lw( XPTR(child_cxy , &process->vmm.gpt.ppn) );
     217
     218    // save CPU registers in local CPU context
     219    hal_do_cpu_save( &context );
     220
     221    // From this point, both parent and child threads execute the following code.
     222    // They can be distinguished by the CURRENT_THREAD value, and child will only
     223    // execute it when it is unblocked by parent, after return to sys_fork().
     224    // - parent thread copies user stack, and patch sp_29 / c0_th / C0_sr / c2_ptpr
     225    // - child thread does nothing
     226
     227    thread_t * current = CURRENT_THREAD;
     228
     229    if( current == parent_ptr )    // current == parent thread
     230    {
     231        // get parent and child stack pointers
     232        char * parent_sp = (char *)context.sp_29;
     233        char * child_sp  = (char *)((intptr_t)parent_sp +
     234                                    (intptr_t)child_ptr -
     235                                    (intptr_t)parent_ptr );
     236 
     237        // patch kernel_stack pointer, current thread, and status slots
     238        context.sp_29   = (uint32_t)child_sp;
     239        context.c0_th   = (uint32_t)child_ptr;
     240        context.c0_sr   = SR_SYS_MODE;
     241        context.c2_ptpr = pt_ppn >> 1;
     242
     243        // copy local context to remote child context)
     244        hal_remote_memcpy( XPTR( child_cxy , child_context_ptr ),
     245                           XPTR( local_cxy  , &context ) ,
     246                           sizeof( hal_cpu_context_t ) );
     247
     248        // copy kernel stack content from local parent thread to remote child thread
     249        uint32_t size = (uint32_t)parent_ptr + CONFIG_THREAD_DESC_SIZE - (uint32_t)parent_sp;
     250        hal_remote_memcpy( XPTR( child_cxy , child_sp ),
     251                           XPTR( local_cxy , parent_sp ),
     252                           size );
     253    }
     254    else                           // current == child thread
     255    {
     256        assert( (current == child_ptr) , __FUNCTION__ , "current = %x / child = %x\n");
     257    }
     258
     259}  // end hal_cpu_context_fork()
     260
    193261/////////////////////////////////////////////////
    194 void hal_cpu_context_display( thread_t * thread )
    195 {
    196     hal_cpu_context_t * ctx = (hal_cpu_context_t *)thread->cpu_context;
    197 
     262void hal_cpu_context_display( xptr_t  thread_xp )
     263{
     264    hal_cpu_context_t * ctx;
     265
     266    // get thread cluster and local pointer
     267    cxy_t      cxy = GET_CXY( thread_xp );
     268    thread_t * ptr = (thread_t *)GET_PTR( thread_xp );
     269
     270    // get context pointer
     271    ctx = (hal_cpu_context_t *)hal_remote_lpt( XPTR( cxy , &ptr->cpu_context ) );
     272
     273    // get relevant context slots values
     274    uint32_t sp_29   = hal_remote_lw( XPTR( cxy , &ctx->sp_29   ) );
     275    uint32_t ra_31   = hal_remote_lw( XPTR( cxy , &ctx->ra_31   ) );
     276    uint32_t c0_sr   = hal_remote_lw( XPTR( cxy , &ctx->c0_sr   ) );
     277    uint32_t c0_epc  = hal_remote_lw( XPTR( cxy , &ctx->c0_epc  ) );
     278    uint32_t c0_th   = hal_remote_lw( XPTR( cxy , &ctx->c0_th   ) );
     279    uint32_t c2_ptpr = hal_remote_lw( XPTR( cxy , &ctx->c2_ptpr ) );
     280    uint32_t c2_mode = hal_remote_lw( XPTR( cxy , &ctx->c2_mode ) );
     281   
    198282    printk("\n***** CPU context for thread %x in process %x / cycle %d\n"
    199            " gp_28   = %X    sp_29   = %X    ra_31   = %X\n"
     283           " sp_29   = %X    ra_31   = %X\n"
    200284           " c0_sr   = %X    c0_epc  = %X    c0_th = %X\n"
    201285           " c2_ptpr = %X    c2_mode = %X\n",
    202            thread->trdid, thread->process->pid, hal_time_stamp(),
    203            ctx->gp_28   , ctx->sp_29   , ctx->ra_31,
    204            ctx->c0_sr   , ctx->c0_epc  , ctx->c0_th,
    205            ctx->c2_ptpr , ctx->c2_mode );
     286           ptr->trdid, ptr->process->pid, hal_time_stamp(),
     287           sp_29   , ra_31,
     288           c0_sr   , c0_epc  , c0_th,
     289           c2_ptpr , c2_mode );
    206290
    207291}  // end hal_cpu_context_display()
     
    270354
    271355//////////////////////////////////////////////
    272 void hal_fpu_context_save( thread_t * thread )
    273 {
    274     uint32_t ctx = (uint32_t)thread->fpu_context;
     356void hal_fpu_context_save( xptr_t  thread_xp )
     357{
     358    // allocate a local FPU context in kernel stack
     359    hal_fpu_context_t  context;
     360
     361    // get remote child cluster and local pointer
     362    cxy_t      thread_cxy = GET_CXY( thread_xp );
     363    thread_t * thread_ptr = (thread_t *)GET_PTR( thread_xp );
    275364
    276365    asm volatile(
     
    309398    "swc1    $f31,  31*4(%0)  \n"   
    310399    ".set reorder             \n"
    311     : : "r"(ctx) );
    312 
    313 }  // end hal_cpu_context_save()
     400    : : "r"(&context) );
     401
     402    // copy local context to remote child context)
     403    hal_remote_memcpy( XPTR( thread_cxy , &thread_ptr->fpu_context ),
     404                       XPTR( local_cxy  , &context ) ,
     405                       sizeof( hal_fpu_context_t ) );
     406
     407}  // end hal_fpu_context_save()
    314408
    315409/////////////////////////////////////////////////
  • trunk/hal/tsar_mips32/core/hal_exception.c

    r407 r408  
    9999xcode_values_t;
    100100
     101////////////////////////////////////////////////////
     102static char * hal_mmu_exception_str( uint32_t code )
     103{
     104    if     ( code == MMU_WRITE_PT1_UNMAPPED        ) return "WRITE_PT1_UNMAPPED";
     105    else if( code == MMU_WRITE_PT2_UNMAPPED        ) return "WRITE_PT2_UNMAPPED";
     106    else if( code == MMU_WRITE_PRIVILEGE_VIOLATION ) return "WRITE_PRIVILEGE_VIOLATION";
     107    else if( code == MMU_WRITE_ACCESS_VIOLATION    ) return "WRITE_ACCESS_VIOLATION";
     108    else if( code == MMU_WRITE_UNDEFINED_XTN       ) return "WRITE_UNDEFINED_XTN";
     109    else if( code == MMU_WRITE_PT1_ILLEGAL_ACCESS  ) return "WRITE_PT1_ILLEGAL_ACCESS";
     110    else if( code == MMU_WRITE_PT2_ILLEGAL_ACCESS  ) return "WRITE_PT2_ILLEGAL_ACCESS";
     111    else if( code == MMU_WRITE_DATA_ILLEGAL_ACCESS ) return "WRITE_DATA_ILLEGAL_ACCESS";
     112    else if( code == MMU_READ_PT1_UNMAPPED         ) return "READ_PT1_UNMAPPED";
     113    else if( code == MMU_READ_PT2_UNMAPPED         ) return "READ_PT2_UNMAPPED";
     114    else if( code == MMU_READ_PRIVILEGE_VIOLATION  ) return "READ_PRIVILEGE_VIOLATION";
     115    else if( code == MMU_READ_EXEC_VIOLATION       ) return "READ_EXEC_VIOLATION";
     116    else if( code == MMU_READ_UNDEFINED_XTN        ) return "READ_UNDEFINED_XTN";
     117    else if( code == MMU_READ_PT1_ILLEGAL_ACCESS   ) return "READ_PT1_ILLEGAL_ACCESS";
     118    else if( code == MMU_READ_PT2_ILLEGAL_ACCESS   ) return "READ_PT2_ILLEGAL_ACCESS";
     119    else if( code == MMU_READ_DATA_ILLEGAL_ACCESS  ) return "READ_DATA_ILLEGAL_ACCESS";
     120    else                                             return "undefined";
     121}
     122
    101123//////////////////////////////////////////////////////////////////////////////////////////
    102124// This function is called when a FPU Coprocessor Unavailable exception has been
     
    120142        if( core->fpu_owner != this )
    121143            {
    122                     hal_fpu_context_save ( core->fpu_owner->fpu_context );
     144                    hal_fpu_context_save( XPTR( local_cxy , core->fpu_owner ) );
    123145        }
    124146        }
     
    179201    }
    180202
    181  excp_dmsg("\n[DBG] %s : core[%x,%d] / is_ins %d / code %x / vaddr %x\n",
    182 __FUNCTION__ , local_cxy , this->core->lid , is_ins, excp_code, bad_vaddr );
     203// @@@
     204thread_t * parent = (thread_t *)0xa4000;
     205uint32_t cond = (this == 0xe0000) && (hal_time_stamp() > 5380000);
     206
     207if( cond ) hal_gpt_display( this->process );
     208if( cond ) hal_gpt_display( parent->process );
     209if( cond ) printk("\n[DBG] %s : core[%x,%d] / is_ins %d / %s / vaddr %x\n",
     210__FUNCTION__ , local_cxy , this->core->lid , is_ins,
     211hal_mmu_exception_str(excp_code) , bad_vaddr );
    183212
    184213   // analyse exception code
     
    217246            return EXCP_USER_ERROR;
    218247        }
    219         case MMU_WRITE_ACCESS_VIOLATION:     // user error or Copy-on-Write
     248        case MMU_WRITE_ACCESS_VIOLATION:     // user error, or Copy-on-Write
    220249        {
    221250            // access page table to get GPT_COW flag
    222251            bool_t cow = hal_gpt_pte_is_cow( &(process->vmm.gpt),
    223                                              bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );  // vpn
     252                                             bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );
    224253
    225254            if( cow )                        // Copy-on-Write
    226255            {
    227256                // try to allocate and copy the page
    228                 error = vmm_copy_on_write( process,
    229                                            bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );  // vpn
     257                error = vmm_handle_cow( process,
     258                                        bad_vaddr >> CONFIG_PPM_PAGE_SHIFT ); 
    230259                if( error )
    231260                {
     
    238267                {
    239268
    240 excp_dmsg("\n[DBG] %s : core[%x,%d] / copy-on-write handled for vaddr = %x\n",
     269if( cond ) printk("\n[DBG] %s : core[%x,%d] / copy-on-write handled for vaddr = %x\n",
    241270__FUNCTION__ , local_cxy , this->core->lid , bad_vaddr );
    242271
     
    274303//////////////////////////////////////////////////////////////////////////////////////////
    275304// @ this     : pointer on faulty thread descriptor.
    276 // @ regs_tbl : pointer on register array.
     305// @ uzone : pointer on register array.
    277306// @ error    : EXCP_USER_ERROR or EXCP_KERNEL_PANIC
    278307//////////////////////////////////////////////////////////////////////////////////////////
    279308static void hal_exception_dump( thread_t * this,
    280                                 reg_t    * regs_tbl,
     309                                reg_t    * uzone,
    281310                                error_t    error )
    282311{
    283     uint32_t  save_sr;
    284     core_t  * core = this->core;
     312    uint32_t    save_sr;
     313    core_t    * core    = this->core;
     314    process_t * process = this->process;
    285315
    286316    // get pointers on TXT0 chdev
     
    297327    if( error == EXCP_USER_ERROR )
    298328    {
    299         nolock_printk("\n========= USER ERROR / core[%x,%d] / cycle %d ==============\n",
    300         local_cxy , core->lid , (uint32_t)hal_get_cycles() );
     329        nolock_printk("\n=== USER ERROR / trdid %x / pid %x / core[%x,%d] / cycle %d ===\n",
     330        this->trdid, process->pid, local_cxy, core->lid , (uint32_t)hal_get_cycles() );
    301331    }
    302332    else
    303333    {
    304         nolock_printk("\n======= KERNEL PANIC / core[%x,%d] / cycle %d ==============\n",
    305         local_cxy , core->lid , (uint32_t)hal_get_cycles() );
     334        nolock_printk("\n=== KERNEL PANIC / trdid %x / pid %x / core[%x,%d] / cycle %d ===\n",
     335        this->trdid, process->pid, local_cxy, core->lid , (uint32_t)hal_get_cycles() );
    306336    }
    307337
    308         nolock_printk("  thread type = %s / trdid = %x / pid %x / core[%x,%d]\n"
    309            "  local locks = %d / remote locks = %d / blocked_vector = %X\n\n",
    310            thread_type_str(this->type), this->trdid, this->process->pid, local_cxy,
    311            this->core->lid, this->local_locks, this->remote_locks, this->blocked );
    312 
    313         nolock_printk("cp0_cr %X   cp0_epc %X   cp0_sr %X   cp2_mode %X\n",
    314                    regs_tbl[UZ_CR], regs_tbl[UZ_EPC], regs_tbl[UZ_SR], regs_tbl[UZ_MODE]);
    315 
    316     nolock_printk("at_01 %X  v0_2  %X  v1_3  %X  a0_4   %X  a1_5   %X\n",
    317                regs_tbl[UZ_AT],regs_tbl[UZ_V0],regs_tbl[UZ_V1],regs_tbl[UZ_A0],regs_tbl[UZ_A1]);
    318 
    319     nolock_printk("a2_6  %X  a3_7  %X  t0_8  %X  t1_9   %X  t2_10  %X\n",
    320                    regs_tbl[UZ_A2],regs_tbl[UZ_A3],regs_tbl[UZ_T0],regs_tbl[UZ_T1],regs_tbl[UZ_T2]);
     338        nolock_printk("local locks = %d / remote locks = %d / blocked_vector = %X\n\n",
     339    this->local_locks, this->remote_locks, this->blocked );
     340
     341    nolock_printk("c0_cr   %X  c0_epc  %X  c0_sr  %X  c0_th  %X\n",
     342    uzone[UZ_CR], uzone[UZ_EPC], uzone[UZ_SR], uzone[UZ_TH] );
     343
     344    nolock_printk("c2_mode %X  c2_ptpr %X\n",
     345    uzone[UZ_MODE], uzone[UZ_PTPR] );
     346
     347    nolock_printk("at_01   %X  v0_2    %X  v1_3   %X  a0_4   %X  a1_5   %X\n",
     348        uzone[UZ_AT], uzone[UZ_V0], uzone[UZ_V1], uzone[UZ_A0], uzone[UZ_A1] );
     349
     350    nolock_printk("a2_6    %X  a3_7    %X  t0_8   %X  t1_9   %X  t2_10  %X\n",
     351        uzone[UZ_A2], uzone[UZ_A3], uzone[UZ_T0], uzone[UZ_T1], uzone[UZ_T2] );
    321352 
    322     nolock_printk("t3_11 %X  t4_12 %X  t5_13 %X  t6_14  %X  t7_15  %X\n",
    323                    regs_tbl[UZ_T3],regs_tbl[UZ_T4],regs_tbl[UZ_T5],regs_tbl[UZ_T6],regs_tbl[UZ_T7]);
    324 
    325     nolock_printk("s0_16 %X  s1_17 %X  s2_18 %X  s3_19  %X  s4_20  %X\n",
    326                    regs_tbl[UZ_S0],regs_tbl[UZ_S1],regs_tbl[UZ_S2],regs_tbl[UZ_S3],regs_tbl[UZ_S4]);
     353    nolock_printk("t3_11   %X  t4_12   %X  t5_13 %X  t6_14  %X  t7_15  %X\n",
     354        uzone[UZ_T3], uzone[UZ_T4], uzone[UZ_T5], uzone[UZ_T6], uzone[UZ_T7] );
     355
     356    nolock_printk("s0_16   %X  s1_17   %X  s2_18 %X  s3_19  %X  s4_20  %X\n",
     357        uzone[UZ_S0], uzone[UZ_S1], uzone[UZ_S2], uzone[UZ_S3], uzone[UZ_S4] );
    327358 
    328     nolock_printk("s5_21 %X  s6_22 %X  s7_23 %X  s8_24  %X  ra_25  %X\n",
    329                regs_tbl[UZ_S5],regs_tbl[UZ_S6],regs_tbl[UZ_S7],regs_tbl[UZ_T8],regs_tbl[UZ_T9]);
    330 
    331     nolock_printk("gp_28 %X  sp_29 %X  S8_30 %X  ra_31  %X\n",
    332                    regs_tbl[UZ_GP],regs_tbl[UZ_SP],regs_tbl[UZ_S8],regs_tbl[UZ_RA]);
     359    nolock_printk("s5_21   %X  s6_22   %X  s7_23 %X  s8_24  %X  ra_25  %X\n",
     360        uzone[UZ_S5], uzone[UZ_S6], uzone[UZ_S7], uzone[UZ_T8], uzone[UZ_T9] );
     361
     362    nolock_printk("gp_28   %X  sp_29   %X  S8_30 %X  ra_31  %X\n",
     363        uzone[UZ_GP], uzone[UZ_SP], uzone[UZ_S8], uzone[UZ_RA] );
    333364
    334365    // release the lock
     
    337368}  // end hal_exception_dump()
    338369
    339 
    340 ///////////////////////////////////////////////////////////////////////////////
    341 // TODO replace the hal_core_sleep() by the generic panic() function.
    342 ///////////////////////////////////////////////////////////////////////////////
    343 void hal_do_exception( thread_t * this,
    344                        reg_t    * regs_tbl )
    345 {
    346         error_t             error;
    347         uint32_t            excCode;                  // 4 bits XCODE from CP0_CR
     370///////////////////////
     371void hal_do_exception()
     372{
     373    uint32_t   * uzone;
     374    thread_t   * this;
     375        error_t      error;
     376        uint32_t     excCode;                  // 4 bits XCODE from CP0_CR
     377
     378    // get pointer on faulty thread uzone
     379    this  = CURRENT_THREAD;
     380    uzone = (uint32_t *)CURRENT_THREAD->uzone;
    348381
    349382    // get 4 bits XCODE from CP0_CR register
    350         excCode        = (regs_tbl[UZ_CR] >> 2) & 0xF;
     383        excCode        = (uzone[UZ_CR] >> 2) & 0xF;
    351384
    352385excp_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / xcode %x / cycle %d\n",
    353386__FUNCTION__, local_cxy, this->core->lid, this->trdid,
    354 this->process->pid, excCode, (uint32_t)hal_get_cycle() );
     387this->process->pid, excCode, (uint32_t)hal_get_cycles() );
    355388
    356389        switch(excCode)
     
    368401            case XCODE_CPU:    // can be non fatal
    369402        {
    370             if( ((regs_tbl[UZ_CR] >> 28) & 0x3) == 1 )  // unavailable FPU
     403            if( ((uzone[UZ_CR] >> 28) & 0x3) == 1 )     // unavailable FPU
    371404            {
    372405                error = hal_fpu_exception( this );
     
    395428        if( error == EXCP_USER_ERROR )          //  user error => kill user process
    396429        {
    397         hal_exception_dump( this , regs_tbl , error );
     430        hal_exception_dump( this , uzone , error );
    398431
    399432        // FIXME : replace this loop by sys_kill()
     
    403436    else if( error == EXCP_KERNEL_PANIC )   // kernel error => kernel panic
    404437    {
    405         hal_exception_dump( this , regs_tbl , error );
    406         hal_core_sleep();
     438        hal_exception_dump( this , uzone , error );
     439        panic( "KERNEL_PANIC for thread %x in process %x on core [%x,%d]/n",
     440        this->trdid , this->process->pid , local_cxy , this->core->lid );
    407441    }
    408442
    409443excp_dmsg("\n[DBG] %s : core[%x,%d] exit / thread %x in process %x / cycle %d\n",
    410 __FUNCTION__, local_cxy, this->core->lid, this->trdid, this->process->pid, hal_time_stamp() );
     444__FUNCTION__, local_cxy, this->core->lid, this->trdid, this->process->pid,
     445(uint32_t)hal_get_cycles() );
    411446
    412447}  // end hal_do_exception()
  • trunk/hal/tsar_mips32/core/hal_gpt.c

    r407 r408  
    170170        error = hal_gpt_set_pte( gpt,
    171171                                 vpn,
    172                                  (local_cxy<<20) | (vpn & 0xFFFFF),
    173                                  attr );
     172                                 attr,
     173                                 (local_cxy<<20) | (vpn & 0xFFFFF) );
    174174
    175175        if( error )
     
    321321                    {
    322322                        vpn = (ix1 << 9) | ix2;
    323                         printk(" - SMALL : vpn = %x / PT2[%d] = %x / pt2[%d] = %x\n",
    324                         vpn , 2*ix2 , pte2_attr , 2*ix2+1 , pte2_ppn );
     323                        printk(" - SMALL : vpn %X / ppn %X / attr %X\n",
     324                        vpn , pte2_ppn , tsar2gpt(pte2_attr) );
    325325                    }
    326326                }
     
    334334error_t hal_gpt_set_pte( gpt_t   * gpt,
    335335                         vpn_t     vpn,
    336                          ppn_t     ppn,
    337                          uint32_t  attr )    // generic GPT attributes
     336                         uint32_t  attr,     // generic GPT attributes
     337                         ppn_t     ppn )
    338338{
    339339    uint32_t          * pt1;                 // PT1 base addres
     
    355355    uint32_t            tsar_attr;           // PTE attributes for TSAR MMU
    356356
    357     gpt_dmsg("\n[DBG] %s : core[%x,%d] enter for vpn = %x / ppn = %x / gpt_attr = %x\n",
    358     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , ppn , attr );
     357gpt_dmsg("\n[DBG] %s : core[%x,%d] enter for vpn = %x / ppn = %x / gpt_attr = %x\n",
     358__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , ppn , attr );
    359359 
    360360    // compute indexes in PT1 and PT2
     
    368368    tsar_attr = gpt2tsar( attr );
    369369
    370     gpt_dmsg("\n[DBG] %s : core[%x,%d] / vpn = %x / &pt1 = %x / tsar_attr = %x\n",
    371     __FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pt1 , tsar_attr );
     370gpt_dmsg("\n[DBG] %s : core[%x,%d] / vpn = %x / &pt1 = %x / tsar_attr = %x\n",
     371__FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pt1 , tsar_attr );
    372372
    373373    // get pointer on PT1[ix1]
     
    400400        pte1 = *pte1_ptr;
    401401       
    402         gpt_dmsg("\n[DBG] %s : core[%x,%d] / vpn = %x / current_pte1 = %x\n",
    403         __FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pte1 );
     402gpt_dmsg("\n[DBG] %s : core[%x,%d] / vpn = %x / current_pte1 = %x\n",
     403__FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pte1 );
    404404       
    405405        // allocate a PT2 if PT1 entry not valid
     
    442442            pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( pt2_ppn ) );
    443443
    444         gpt_dmsg("\n[DBG] %s : core[%x,%d] / vpn = %x / pte1 = %x / &pt2 = %x\n",
    445         __FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pte1 , pt2 );
     444gpt_dmsg("\n[DBG] %s : core[%x,%d] / vpn = %x / pte1 = %x / &pt2 = %x\n",
     445__FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pte1 , pt2 );
    446446       
    447447    }
     
    454454        hal_fence();
    455455
    456     gpt_dmsg("\n[DBG] %s : core[%x,%d] exit / vpn = %x / pte2_attr = %x / pte2_ppn = %x\n",
    457     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn ,
    458     pt2[2 * ix2] , pt2[2 * ix2 + 1] );
     456gpt_dmsg("\n[DBG] %s : core[%x,%d] exit / vpn = %x / pte2_attr = %x / pte2_ppn = %x\n",
     457__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn ,
     458pt2[2 * ix2] , pt2[2 * ix2 + 1] );
    459459 
    460460        return 0;
     
    728728}  // end hal_gpt_unlock_pte()
    729729
    730 ///////////////////////////////////////
    731 error_t hal_gpt_copy( gpt_t  * dst_gpt,
    732                       gpt_t  * src_gpt,
    733                       vpn_t    vpn_base,
    734                       vpn_t    vpn_size,
    735                       bool_t   cow )
    736 {
    737     vpn_t        vpn;       // current vpn
    738 
     730///////////////////////////////////////////
     731error_t hal_gpt_pte_copy( gpt_t  * dst_gpt,
     732                          xptr_t   src_gpt_xp,
     733                          vpn_t    vpn,
     734                          bool_t   cow,
     735                          ppn_t  * ppn,
     736                          bool_t * mapped )
     737{
    739738    uint32_t     ix1;       // index in PT1
    740739    uint32_t     ix2;       // index in PT2
    741740
    742         uint32_t   * src_pt1;   // local pointer on PT1 for SRC_GPT
    743         uint32_t   * dst_pt1;   // local pointer on PT1 for DST_GPT
    744     uint32_t   * dst_pt2;   // local pointer on PT2 for DST_GPT
    745     uint32_t   * src_pt2;   // local pointer on PT2 for SRC_GPT
     741    cxy_t        src_cxy;   // SRC GPT cluster
     742    gpt_t      * src_gpt;   // SRC GPT local pointer
     743
     744        uint32_t   * src_pt1;   // local pointer on SRC PT1
     745        uint32_t   * dst_pt1;   // local pointer on DST PT1
     746    uint32_t   * src_pt2;   // local pointer on SRC PT2
     747    uint32_t   * dst_pt2;   // local pointer on DST PT2
    746748
    747749        kmem_req_t   req;       // for dynamic PT2 allocation
     
    750752    uint32_t     dst_pte1;
    751753
    752     uint32_t     pte2_attr;
    753     uint32_t     pte2_ppn;
     754    uint32_t     src_pte2_attr;
     755    uint32_t     src_pte2_ppn;
    754756
    755757    page_t     * page;
     
    759761    ppn_t        dst_pt2_ppn;
    760762
    761 gpt_dmsg("\n[DBG] %s : core[%x,%d] enter\n",
    762 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
    763 
    764     // check page size
    765     assert( (CONFIG_PPM_PAGE_SIZE == 4096) , __FUNCTION__ ,
    766     "for TSAR, the page must be 4 Kbytes\n" );
    767 
    768     // check SRC_PT1 and DST_PT1 existence
    769     assert( (src_gpt->ptr != NULL) , __FUNCTION__ , "SRC_PT1 does not exist\n");
    770     assert( (dst_gpt->ptr != NULL) , __FUNCTION__ , "DST_PT1 does not exist\n");
    771 
    772     // get pointers on SRC_PT1 and DST_PT1
    773     src_pt1 = (uint32_t *)src_gpt->ptr;
     763gpt_dmsg("\n[DBG] %s : core[%x,%d] enter for vpn %x\n",
     764__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn );
     765
     766    // get remote src_gpt cluster and local pointer
     767    src_cxy = GET_CXY( src_gpt_xp );
     768    src_gpt = (gpt_t *)GET_PTR( src_gpt_xp );
     769
     770    // get remote src_pt1 and local dst_pt1
     771    src_pt1 = (uint32_t *)hal_remote_lpt( XPTR( src_cxy , &src_gpt->ptr ) );
    774772    dst_pt1 = (uint32_t *)dst_gpt->ptr;
    775773
    776     // scan pages in vseg
    777     for( vpn = vpn_base ; vpn < (vpn_base + vpn_size) ; vpn++ )
    778     {
    779         ix1 = TSAR_MMU_IX1_FROM_VPN( vpn );
    780         ix2 = TSAR_MMU_IX2_FROM_VPN( vpn );
    781 
    782         // get SRC_PT1 entry
    783         src_pte1 = src_pt1[ix1];
    784 
    785         // do nothing if SRC_PTE1 unmapped
    786                 if( (src_pte1 & TSAR_MMU_MAPPED) != 0 )   // SRC_PTE1 is mapped
     774    // check src_pt1 and dst_pt1 existence
     775    assert( (src_pt1 != NULL) , __FUNCTION__ , "src_pt1 does not exist\n");
     776    assert( (dst_pt1 != NULL) , __FUNCTION__ , "dst_pt1 does not exist\n");
     777
     778    ix1 = TSAR_MMU_IX1_FROM_VPN( vpn );
     779    ix2 = TSAR_MMU_IX2_FROM_VPN( vpn );
     780
     781    // get src_pte1
     782    src_pte1 = hal_remote_lw( XPTR( src_cxy , &src_pt1[ix1] ) );
     783
     784    // do nothing if src_pte1 not MAPPED or not SMALL
     785        if( (src_pte1 & TSAR_MMU_MAPPED) && (src_pte1 & TSAR_MMU_SMALL) )   
     786    {
     787        // get dst_pt1 entry
     788        dst_pte1 = dst_pt1[ix1];
     789
     790        // map dst_pte1 if required
     791        if( (dst_pte1 & TSAR_MMU_MAPPED) == 0 )
     792        {
     793            // allocate one physical page for a new PT2
     794                req.type  = KMEM_PAGE;
     795                req.size  = 0;                     // 1 small page
     796                req.flags = AF_KERNEL | AF_ZERO;
     797                page = (page_t *)kmem_alloc( &req );
     798
     799            if( page == NULL )
     800            {
     801                        printk("\n[ERROR] in %s : cannot allocate PT2\n", __FUNCTION__ );
     802                return -1;
     803            }
     804
     805            // build extended pointer on page descriptor
     806            page_xp = XPTR( local_cxy , page );
     807
     808            // get PPN for this new PT2
     809            dst_pt2_ppn = (ppn_t)ppm_page2ppn( page_xp );
     810
     811            // build the new dst_pte1
     812            dst_pte1 = TSAR_MMU_MAPPED | TSAR_MMU_SMALL | dst_pt2_ppn;
     813
     814            // register it in DST_GPT
     815            dst_pt1[ix1] = dst_pte1;
     816        }
     817
     818        // get pointer on src_pt2
     819        src_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( src_pte1 );
     820        src_pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( src_pt2_ppn ) );
     821
     822        // get pointer on dst_pt2
     823        dst_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( dst_pte1 );
     824        dst_pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( dst_pt2_ppn ) );
     825
     826        // get attr and ppn from SRC_PT2
     827        src_pte2_attr = hal_remote_lw( XPTR( src_cxy , &src_pt2[2 * ix2]     ) );
     828        src_pte2_ppn  = hal_remote_lw( XPTR( src_cxy , &src_pt2[2 * ix2 + 1] ) );
     829
     830        // do nothing if src_pte2 not MAPPED
     831        if( (src_pte2_attr & TSAR_MMU_MAPPED) != 0 ) 
    787832        {
    788             assert( (src_pte1 & TSAR_MMU_SMALL) , __FUNCTION__ ,
    789             "no BIG page for user process in TSAR architecture\n" );
    790 
    791             // get DST_PT1 entry
    792             dst_pte1 = dst_pt1[ix1];
    793 
    794             // map dst_pte1 if required
    795             if( (dst_pte1 & TSAR_MMU_MAPPED) == 0 )
    796             {
    797                 // allocate one physical page for a new DST_PT2
    798                     req.type  = KMEM_PAGE;
    799                     req.size  = 0;                     // 1 small page
    800                     req.flags = AF_KERNEL | AF_ZERO;
    801                     page = (page_t *)kmem_alloc( &req );
    802 
    803                 if( page == NULL )
    804                 {
    805                                 printk("\n[ERROR] in %s : cannot allocate PT2\n", __FUNCTION__ );
    806                     return ENOMEM;
    807                 }
    808 
    809                 // build extended pointer on page descriptor
    810                 page_xp = XPTR( local_cxy , page );
    811 
    812                 // get PPN for this new DST_PT2
    813                 dst_pt2_ppn    = (ppn_t)ppm_page2ppn( page_xp );
    814 
    815                 // build the new dst_pte1
    816                 dst_pte1 = TSAR_MMU_MAPPED | TSAR_MMU_SMALL | dst_pt2_ppn;
    817 
    818                 // register it in DST_GPT
    819                 dst_pt1[ix1] = dst_pte1;
     833            // set PPN in DST PTE2
     834            dst_pt2[2*ix2+1] = src_pte2_ppn;
     835                       
     836            // set attributes in DST PTE2         
     837            if( cow && (src_pte2_attr & TSAR_MMU_WRITABLE) )
     838            {
     839                dst_pt2[2*ix2] = (src_pte2_attr | TSAR_MMU_COW) & (~TSAR_MMU_WRITABLE);
     840            }
     841            else
     842            {
     843                dst_pt2[2*ix2] = src_pte2_attr;
    820844            }
    821845
    822             // get PPN and pointer on SRC_PT2
    823             src_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( src_pte1 );
    824             src_pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( src_pt2_ppn ) );
    825 
    826             // get PPN and pointer on DST_PT2
    827             dst_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( dst_pte1 );
    828             dst_pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( dst_pt2_ppn ) );
    829 
    830             // get attr and ppn from SRC_PT2
    831             pte2_attr = TSAR_MMU_ATTR_FROM_PTE2( src_pt2[2 * ix2] );
    832             pte2_ppn  = TSAR_MMU_PPN_FROM_PTE2(  src_pt2[2 * ix2 + 1] );
    833 
    834             // no copy if SRC_PTE2 unmapped
    835             if( (pte2_attr & TSAR_MMU_MAPPED) != 0 )  // valid PTE2 in SRC_GPT
    836             {
    837                 // set a new PTE2 in DST_PT2
    838                 dst_pt2[2*ix2]     = pte2_attr;
    839                 dst_pt2[2*ix2 + 1] = pte2_ppn;
    840                        
    841                 // FIXME increment page descriptor refcount for the referenced page
    842 
    843                 // handle Copy-On-Write
    844                 if( cow && (pte2_attr & TSAR_MMU_WRITABLE) )
    845                 {
    846                     // reset WRITABLE flag in DST_GPT
    847                     hal_atomic_and( &dst_pt2[2*ix2] , ~TSAR_MMU_WRITABLE );
    848 
    849                     // set COW flag in DST_GPT
    850                     hal_atomic_or( &dst_pt2[2*ix2] , TSAR_MMU_COW );
    851                 }
    852             }
    853         }   // end if PTE1 mapped
    854     }   // end loop on vpn
     846            // return "successfully copied"
     847            *mapped = true;
     848            *ppn    = src_pte2_ppn;
     849       
     850gpt_dmsg("\n[DBG] %s : core[%x,%d] exit for vpn %x / copy done\n",
     851__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn );
     852
     853            hal_fence();
     854
     855            return 0;
     856        }   // end if PTE2 mapped
     857    }   // end if PTE1 mapped
     858
     859    // return "nothing done"
     860    *mapped = false;
     861    *ppn    = 0;
     862   
     863gpt_dmsg("\n[DBG] %s : core[%x,%d] exit for vpn %x / nothing done\n",
     864__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn );
    855865
    856866    hal_fence();
    857867
    858 gpt_dmsg("\n[DBG] %s : core[%x,%d] exit\n",
    859 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
    860 
    861868    return 0;
    862869
    863 }  // end hal_gpt_copy()
     870}  // end hal_gpt_pte_copy()
     871
     872//////////////////////////////////////////
     873bool_t hal_gpt_pte_is_mapped( gpt_t * gpt,
     874                              vpn_t   vpn )
     875{
     876    uint32_t * pt1;
     877    uint32_t   pte1;
     878    uint32_t   pte2_attr;
     879
     880    uint32_t * pt2;
     881    ppn_t      pt2_ppn;
     882
     883    uint32_t   ix1 = TSAR_MMU_IX1_FROM_VPN( vpn );
     884    uint32_t   ix2 = TSAR_MMU_IX2_FROM_VPN( vpn );
     885
     886    // get PTE1 value
     887        pt1  = gpt->ptr;
     888    pte1 = pt1[ix1];
     889
     890        if( (pte1 & TSAR_MMU_MAPPED) == 0 ) return false;
     891
     892        if( (pte1 & TSAR_MMU_SMALL) == 0 ) return false;
     893
     894    // compute PT2 base address
     895    pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 );
     896    pt2     = (uint32_t*)GET_PTR( ppm_ppn2base( pt2_ppn ) );
     897
     898    // get pte2_attr
     899    pte2_attr = pt2[2*ix2];
     900
     901    if( (pte2_attr & TSAR_MMU_MAPPED) == 0 ) return false;
     902    else                                     return true;
     903
     904}   // end hal_gpt_pte_is_mapped()
    864905
    865906///////////////////////////////////////
     
    869910    uint32_t * pt1;
    870911    uint32_t   pte1;
     912    uint32_t   pte2_attr;
    871913
    872914    uint32_t * pt2;
     
    880922    pte1 = pt1[ix1];
    881923
    882         if( (pte1 & TSAR_MMU_MAPPED) == 0 )    // PT1 entry not mapped
    883         {
    884                 return false;
    885         }
    886 
    887         if( (pte1 & TSAR_MMU_SMALL) == 0 )     // it's a PTE1
    888         {
    889                 return false;
    890         }
    891     else                                   // it's a PTD1
    892     {
    893         // compute PT2 base address
    894         pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 );
    895         pt2     = (uint32_t*)GET_PTR( ppm_ppn2base( pt2_ppn ) );
    896 
    897         if( pt2[2*ix2] & TSAR_MMU_COW ) return true;
    898         else                            return false;
    899     }
     924        if( (pte1 & TSAR_MMU_MAPPED) == 0 ) return false;
     925
     926        if( (pte1 & TSAR_MMU_SMALL) == 0 ) return false;
     927
     928    // compute PT2 base address
     929    pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 );
     930    pt2     = (uint32_t*)GET_PTR( ppm_ppn2base( pt2_ppn ) );
     931
     932    // get pte2_attr
     933    pte2_attr = pt2[2*ix2];
     934
     935if( (CURRENT_THREAD == 0xe0000) && (hal_time_stamp() > 5380000) )
     936printk("\n@@@ %s : vpn = %X / attr = %X\n", __FUNCTION__ , vpn , tsar2gpt( pte2_attr ) );
     937
     938    if( (pte2_attr & TSAR_MMU_MAPPED) == 0 ) return false;
     939
     940    if( (pte2_attr & TSAR_MMU_COW)    == 0 ) return false;
     941    else                                     return true;
     942
    900943}   // end hal_gpt_pte_is_cow()
    901944
    902 
    903 
    904 
    905 
    906 
    907 
    908 
    909 
    910 
    911 
    912 
    913 /* deprecated : old hal_gpt_copy [AG]
    914  
    915     // scan the SRC_PT1
    916         for( ix1 = 0 ; ix1 < 2048 ; ix1++ )
    917         {
    918         pte1 = src_pt1[ix1];
    919                 if( (pte1 & TSAR_MMU_MAPPED) != 0 )
     945/////////////////////////////////////////
     946void hal_gpt_flip_cow( bool_t  set_cow,
     947                       xptr_t  gpt_xp,
     948                       vpn_t   vpn_base,
     949                       vpn_t   vpn_size )
     950{
     951    cxy_t      gpt_cxy;
     952    gpt_t    * gpt_ptr;
     953
     954    vpn_t      vpn;
     955
     956    uint32_t   ix1;
     957    uint32_t   ix2;
     958
     959    uint32_t * pt1;
     960    uint32_t   pte1;
     961
     962    uint32_t * pt2;
     963    ppn_t      pt2_ppn;
     964
     965    uint32_t   old_attr;
     966    uint32_t   new_attr;
     967
     968    // get GPT cluster and local pointer
     969    gpt_cxy = GET_CXY( gpt_xp );
     970    gpt_ptr = (gpt_t *)GET_PTR( gpt_xp );
     971
     972    // get local PT1 pointer
     973    pt1 = (uint32_t *)hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) );
     974
     975    // loop on pages
     976    for( vpn = vpn_base ; vpn < (vpn_base + vpn_size) ; vpn++ )
     977    {
     978        ix1 = TSAR_MMU_IX1_FROM_VPN( vpn );
     979        ix2 = TSAR_MMU_IX2_FROM_VPN( vpn );
     980
     981        // get PTE1 value
     982        pte1 = hal_remote_lw( XPTR( gpt_cxy , &pt1[ix1] ) );
     983
     984        // only MAPPED & SMALL PTEs are modified
     985            if( (pte1 & TSAR_MMU_MAPPED) && (pte1 & TSAR_MMU_SMALL) )
    920986        {
    921             if( (pte1 & TSAR_MMU_SMALL) == 0 )  // PTE1 => big kernel page
     987            // compute PT2 base address
     988            pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 );
     989            pt2     = (uint32_t*)GET_PTR( ppm_ppn2base( pt2_ppn ) );
     990
     991            assert( (GET_CXY( ppm_ppn2base( pt2_ppn ) ) == gpt_cxy ), __FUNCTION__,
     992            "PT2 and PT1 must be in the same cluster\n");
     993 
     994            // get current PTE2 attributes
     995            old_attr = hal_remote_lw( XPTR( gpt_cxy , &pt2[2*ix2] ) );
     996
     997            // only MAPPED PTEs are modified       
     998            if( old_attr & TSAR_MMU_MAPPED )
    922999            {
    923                 // big kernel pages are shared by all processes => copy it
    924                 dst_pt1[ix1] = pte1;
    925             }
    926             else                           // PTD1 => smal pages
    927             {
    928                 // allocate one physical page for a PT2 in DST_GPT
    929                     kmem_req_t req;
    930                     req.type  = KMEM_PAGE;
    931                     req.size  = 0;                     // 1 small page
    932                     req.flags = AF_KERNEL | AF_ZERO;
    933                     page = (page_t *)kmem_alloc( &req );
    934 
    935                 if( page == NULL )
    936                 {
    937                     // TODO release all memory allocated to DST_GPT
    938                                 printk("\n[ERROR] in %s : cannot allocate PT2\n", __FUNCTION__ );
    939                     return ENOMEM;
     1000                if( (set_cow != 0) && (old_attr & TSAR_MMU_WRITABLE) )
     1001                {
     1002                    new_attr = (old_attr | TSAR_MMU_COW) & (~TSAR_MMU_WRITABLE);
     1003                    hal_remote_sw( XPTR( gpt_cxy , &pt2[2*ix2] ) , new_attr );
    9401004                }
    941 
    942                 // get extended pointer on page descriptor
    943                 page_xp = XPTR( local_cxy , page );
    944 
    945                 // get pointer on new PT2 in DST_GPT
    946                 xptr_t base_xp = ppm_page2base( page_xp );
    947                 dst_pt2 = (uint32_t *)GET_PTR( base_xp );
    948 
    949                 // set a new PTD1 in DST_GPT
    950                 dst_pt2_ppn  = (ppn_t)ppm_page2ppn( page_xp );
    951                 dst_pt1[ix1] = TSAR_MMU_MAPPED | TSAR_MMU_SMALL | dst_pt2_ppn;
    952 
    953                 // get pointer on PT2 in SRC_GPT
    954                 src_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( pte1 );
    955                 src_pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( src_pt2_ppn ) );
    956 
    957                 // scan the SRC_PT2
    958                 for( ix2 = 0 ; ix2 < 512 ; ix2++ )
    959                 {
    960                     // get attr & ppn from PTE2
    961                     pte2_attr = TSAR_MMU_ATTR_FROM_PTE2( src_pt2[2 * ix2] );
    962 
    963                             if( (pte2_attr & TSAR_MMU_MAPPED) != 0 )  // valid PTE2 in SRC_GPT
    964                     {
    965                         // get GPT_WRITABLE & PPN
    966                         pte2_writable = pte2_attr & GPT_WRITABLE;
    967                         pte2_ppn      = TSAR_MMU_PPN_FROM_PTE2(  src_pt2[2 * ix2 + 1] );
    968 
    969                         // set a new PTE2 in DST_GPT
    970                         dst_pt2[2*ix2]     = pte2_attr;
    971                         dst_pt2[2*ix2 + 1] = pte2_ppn;
    972                        
    973                         // handle Copy-On-Write
    974                         if( cow && pte2_writable )
    975                         {
    976                             // reset GPT_WRITABLE in both SRC_GPT and DST_GPT
    977                             hal_atomic_and( &dst_pt2[2*ix2] , ~GPT_WRITABLE );
    978                             hal_atomic_and( &src_pt2[2*ix2] , ~GPT_WRITABLE );
    979 
    980                             // register PG_COW in page descriptor
    981                             page = (page_t *)GET_PTR( ppm_ppn2page( pte2_ppn ) );
    982                             hal_atomic_or( &page->flags , PG_COW );
    983                                                         hal_atomic_add( &page->fork_nr , 1 );
    984                         }
    985                     }
    986                 }  // end loop on ix2
    987             }
    988         }
    989     }  // end loop ix1
    990 
    991     hal_fence();
    992 
    993     return 0;
    994 
    995 }  // end hal_gpt_copy()
    996 
    997 */
     1005                if( (set_cow == 0) && (old_attr & TSAR_MMU_COW ) )
     1006                {
     1007                    new_attr = (old_attr | TSAR_MMU_WRITABLE) & (~TSAR_MMU_COW);
     1008                    hal_remote_sw( XPTR( gpt_cxy , &pt2[2*ix2] ) , new_attr );
     1009                }
     1010            }   // end if PTE2 mapped
     1011        }   // end if PTE1 mapped
     1012    }   // end loop on pages
     1013
     1014}  // end hal_gpt_flip_cow()
     1015
     1016//////////////////////////////////////////
     1017void hal_gpt_update_pte( xptr_t    gpt_xp,
     1018                         vpn_t     vpn,
     1019                         uint32_t  attr,     // generic GPT attributes
     1020                         ppn_t     ppn )
     1021{
     1022    uint32_t          * pt1;                 // PT1 base addres
     1023        uint32_t            pte1;                // PT1 entry value
     1024
     1025        ppn_t               pt2_ppn;             // PPN of PT2
     1026        uint32_t          * pt2;                 // PT2 base address
     1027
     1028    uint32_t            ix1;                 // index in PT1
     1029    uint32_t            ix2;                 // index in PT2
     1030
     1031    uint32_t            tsar_attr;           // PTE attributes for TSAR MMU
     1032
     1033    // check attr argument MAPPED and SMALL
     1034    if( (attr & GPT_MAPPED) == 0 )  return;
     1035    if( (attr & GPT_SMALL ) == 0 )  return;
     1036
     1037    // get cluster and local pointer on remote GPT
     1038    cxy_t   gpt_cxy = GET_CXY( gpt_xp );
     1039    gpt_t * gpt_ptr = (gpt_t *)GET_PTR( gpt_xp );
     1040
     1041    // compute indexes in PT1 and PT2
     1042    ix1 = TSAR_MMU_IX1_FROM_VPN( vpn );
     1043    ix2 = TSAR_MMU_IX2_FROM_VPN( vpn );
     1044
     1045    // get PT1 base
     1046    pt1 = (uint32_t *)hal_remote_lpt( XPTR( gpt_cxy , &gpt_ptr->ptr ) );
     1047
     1048    // compute tsar_attr from generic attributes
     1049    tsar_attr = gpt2tsar( attr );
     1050
     1051    // get PTE1 value
     1052    pte1 = hal_remote_lw( XPTR( gpt_cxy , &pt1[ix1] ) );
     1053
     1054    if( (pte1 & TSAR_MMU_MAPPED) == 0 ) return;
     1055    if( (pte1 & TSAR_MMU_SMALL ) == 0 ) return;
     1056
     1057    // get PT2 base from PTE1
     1058    pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 );
     1059    pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( pt2_ppn ) );
     1060
     1061    // reset PTE2
     1062        hal_remote_sw( XPTR( gpt_cxy, &pt2[2 * ix2]     ) , 0 );
     1063        hal_fence();
     1064
     1065    // set PTE2 in this order
     1066        hal_remote_sw( XPTR( gpt_cxy, &pt2[2 * ix2 + 1] ) , ppn );
     1067        hal_fence();
     1068        hal_remote_sw( XPTR( gpt_cxy, &pt2[2 * ix2]     ) , tsar_attr );
     1069        hal_fence();
     1070
     1071} // end hal_gpt_update_pte()
     1072
  • trunk/hal/tsar_mips32/core/hal_interrupt.c

    r407 r408  
    2929#include <soclib_pic.h>
    3030
    31 ///////////////////////////////////////
    32 void hal_do_interrupt( thread_t * this,
    33                                reg_t    * regs_tbl )
     31///////////////////////
     32void hal_do_interrupt()
    3433{
    3534
  • trunk/hal/tsar_mips32/core/hal_kentry.S

    r407 r408  
    4040#define      UZ_T6           14
    4141#define      UZ_T7           15
    42 #define      UZ_T8           16
    43 #define      UZ_T9           17
    44 #define      UZ_S0           18
    45 #define      UZ_S1           19
    46 #define      UZ_S2           20
    47 #define      UZ_S3           21
    48 #define      UZ_S4           22
    49 #define      UZ_S5           23
    50 #define      UZ_S6           24
    51 #define      UZ_S7           25
    52 #define      UZ_S8           26
    53 #define      UZ_GP           27
    54 #define      UZ_RA           28
    55 #define      UZ_EPC          29
    56 #define      UZ_CR           30
    57 #define      UZ_SP           31
    58 #define      UZ_SR           32
    59 #define      UZ_LO           33
    60 #define      UZ_HI           34
    61 
    62 #define      UZ_REGS         35
     42#define      UZ_S0           16
     43#define      UZ_S1           17
     44#define      UZ_S2           18
     45#define      UZ_S3           19
     46#define      UZ_S4           20
     47#define      UZ_S5           21
     48#define      UZ_S6           22
     49#define      UZ_S7           23
     50#define      UZ_T8           24
     51#define      UZ_T9           25
     52
     53#define      UZ_LO           26
     54#define      UZ_HI           27
     55
     56#define      UZ_GP           28
     57#define      UZ_SP           29
     58#define      UZ_S8           30
     59#define      UZ_RA           31
     60#define      UZ_PTPR         32
     61#define      UZ_EPC          33
     62#define      UZ_SR           34
     63#define      UZ_TH           35
     64#define      UZ_CR           36
     65
     66#define      UZ_REGS         37
    6367
    6468#include <kernel_config.h>
     
    6973        .extern    hal_do_exception
    7074        .extern    hal_do_syscall
    71         .extern    cluster_core_kernel_enter
    72         .extern    cluster_core_kentry_exit
     75    .extern    puts
     76    .extern    putx
     77    .extern    putl
    7378
    7479        .org       0x180
     
    8085        .set       noreorder
    8186
    82 #---------------------------------------------------------------------------------
     87#------------------------------------------------------------------------------------
    8388# Kernel Entry point for Interrupt / Exception / Syscall
    8489# The c2_dext and c2_iext CP2 registers must have been previously set
    8590# to "local_cxy", because the kernel run with MMU desactivated.
    86 #---------------------------------------------------------------------------------
     91#------------------------------------------------------------------------------------
    8792
    8893hal_kentry_enter:
     
    9398        ori     $27,    $0,       0x3           # $27 <= code for MMU OFF
    9499       
    95 #---------------------------------------------------------------------------------------       
     100#------------------------------------------------------------------------------------
    96101# This code is executed when the core is in user mode:
    97102# - save current c2_mode in $26.
     
    106111    move    $27,    $29                 # $27 <= user stack pointer
    107112        mfc0    $29,    $4,   2             # get pointer on thread descriptor from c0_th
    108     addi    $29,    $29,    CONFIG_THREAD_DESC_SIZE
    109     addi    $29,    $29,    -8          # $29 <= kernel stack pointer
     113    addi    $29,    $29,  CONFIG_THREAD_DESC_SIZE
     114    addi    $29,    $29,  -8            # $29 <= kernel stack pointer
    110115    j       unified_mode
    111116    nop
    112117
    113 #---------------------------------------------------------------------------------------       
     118#------------------------------------------------------------------------------------
    114119# This code is executed when the core is already in kernel mode:
    115120# - save current c2_mode in $26.
     
    123128    move    $27,    $29                 # $27 <= current kernel stack pointer
    124129
    125 #---------------------------------------------------------------------------------------       
     130#------------------------------------------------------------------------------------   
    126131# This code is executed in both modes (user or kernel):
    127132# The assumptions are:
     
    131136# - $29 contains the kernel stack pointer.
    132137# We execute the following actions:
    133 # - allocate an uzone in kernel stack, incrementing $29
    134 # - save relevant registers to uzone.
     138# - allocate an uzone in kernel stack, decrementing $29.
     139# - save relevant GPR, CP0 and CP2 registers to uzone.
    135140# - set the SR in kernel mode: IRQ disabled, clear exl.
    136 # - signal the kernel entry.
    137141
    138142unified_mode:
     
    166170        sw      $25,    (UZ_T9*4)($29)
    167171
    168         sw      $26,    (UZ_MODE*4)($29)    # save c2_mode
    169         sw      $27,    (UZ_SP*4)($29)      # save sp
    170 
    171         sw          $28,        (UZ_GP*4)($29)
    172         sw          $30,        (UZ_S8*4)($29)
    173         sw          $31,        (UZ_RA*4)($29)
    174 
    175         mfc0    $16,    $14
    176         sw      $16,    (UZ_EPC*4)($29)     # save c0_epc
    177         mflo    $14
    178         sw      $14,    (UZ_LO*4)($29)      # save lo
    179         mfhi    $15
    180         sw      $15,    (UZ_HI*4)($29)          # save hi
    181         mfc0    $18,    $12
    182         sw          $18,        (UZ_SR*4)($29)          # save c0_sr
    183         mfc0    $17,    $13
    184         sw      $17,    (UZ_CR*4)($29)          # save c0_cr
    185         mfc2    $26,    $1
    186 
    187         srl         $3,     $18,  5
    188         sll     $3,         $3,   5     
    189         mtc0    $3,         $12                         # set new sr
    190 
    191 #---------------------------------------------------------------------------------------
    192 # This code call the relevant Interrupt / Exception / Syscall handler,
     172        mflo    $1
     173        sw      $1,     (UZ_LO*4)($29)      # save lo
     174        mflo    $1
     175        sw      $1,     (UZ_HI*4)($29)      # save hi
     176
     177        sw          $28,        (UZ_GP*4)($29)      # save gp
     178        sw          $27,        (UZ_SP*4)($29)      # save previous sp (can be usp or ksp)
     179        sw          $30,        (UZ_S8*4)($29)      # save s8
     180        sw          $31,        (UZ_RA*4)($29)      # save ra
     181
     182        mfc0    $1,     $14
     183        sw      $1,     (UZ_EPC*4)($29)     # save c0_epc
     184        mfc0    $1,         $12
     185        sw          $1,     (UZ_SR*4)($29)              # save c0_sr
     186        mfc0    $1,     $4,  2
     187        sw      $1,         (UZ_TH*4)($29)              # save c0_th
     188        mfc0    $1,     $13   
     189        sw      $1,         (UZ_CR*4)($29)              # save c0_cr
     190        mfc2    $1,     $0
     191        sw      $1,     (UZ_PTPR*4)($29)        # save c2_ptpr
     192
     193    sw      $26,    (UZ_MODE*4)($29)    # save previous c2_mode (can be user or kernel)
     194
     195    mfc0    $3,     $12
     196        srl         $3,     $3,   5
     197        sll     $3,         $3,   5                 # reset 5 LSB bits
     198        mtc0    $3,         $12                         # set new c0_sr
     199
     200#if CONFIG_KENTRY_DEBUG
     201
     202    # display "enter" message
     203    la      $4,     msg_enter
     204    jal     puts
     205    nop
     206    move    $4,     $29
     207    jal     putx
     208    nop
     209    la      $4,     msg_crlf
     210    jal     puts
     211    nop   
     212    # display saved SP value
     213    la      $4,     msg_sp
     214    jal     puts
     215    nop
     216    lw      $4,         (UZ_SP*4)($29)
     217    jal     putx
     218    nop
     219    la      $4,     msg_crlf
     220    jal     puts
     221    nop   
     222    # display saved RA value
     223    la      $4,     msg_ra
     224    jal     puts
     225    nop
     226    lw      $4,         (UZ_RA*4)($29)
     227    jal     putx
     228    nop
     229    la      $4,     msg_crlf
     230    jal     puts
     231    nop   
     232    # display saved TH value
     233    la      $4,     msg_th
     234    jal     puts
     235    nop
     236    lw      $4,         (UZ_TH*4)($29)
     237    jal     putx
     238    nop
     239    la      $4,     msg_crlf
     240    jal     puts
     241    nop   
     242    # display saved EPC value
     243    la      $4,     msg_epc
     244    jal     puts
     245    nop
     246    lw      $4,         (UZ_EPC*4)($29)
     247    jal     putx
     248    nop
     249    la      $4,     msg_crlf
     250    jal     puts
     251    nop   
     252    # display saved MODE value
     253    la      $4,     msg_mode
     254    jal     puts
     255    nop
     256    lw      $4,         (UZ_MODE*4)($29)
     257    jal     putx
     258    nop
     259    la      $4,     msg_crlf
     260    jal     puts
     261    nop   
     262    # display saved V0 value
     263    la      $4,     msg_v0
     264    jal     puts
     265    nop
     266    lw      $4,         (UZ_V0*4)($29)
     267    jal     putx
     268    nop
     269    la      $4,     msg_crlf
     270    jal     puts
     271    nop   
     272       
     273#endif
     274   
     275#------------------------------------------------------------------------------------
     276# This code update the uzone field in thread descriptor,
     277# and call the relevant Interrupt / Exception / Syscall handler,
    193278# depending on XCODE in CP0_CR.
    194279# assumption: $29 contains the kernel stack pointer, that is the uzone base.
    195 # The three handlers take the same two arguments: thread pointer and uzone pointer.
    196 # The uzone pointer is saved in $19 to be used by kentry_exit.
    197280
    198281        mfc0    $17,    $13                 # $17 <= CR
    199282        andi    $17,    $17,   0x3F         # $17 <= XCODE
    200283
    201         mfc0    $4,     $4,   2             # $4 <= thread pointer (first arg)
    202         or          $5,     $0,   $29               # $5 <= uzone pointer (second arg)
    203         or          $19,    $0,   $29           # $19 <= &uzone (for kentry_exit)
    204 
    205         ori         $8,     $0,   0x20          # $8 <= cause syscall
     284        mfc0    $4,     $4,   2             # $4 <= pointer on thread desc
     285    sw      $29,    8($4)               # update uzone pointer in thread desc
     286
     287        ori         $8,     $0,   0x20
    206288    beq     $8,     $17,  cause_sys     # go to syscall handler
    207289    nop
     
    210292
    211293cause_excp:
    212         la      $1,         hal_do_exception
    213         jalr    $1                              # call exception handler
    214         addiu   $29,    $29,  -8                # hal_do_exception has 2 args
    215         addiu   $29,    $29,  8
     294        jal     hal_do_exception            # call exception handler
     295        nop
    216296        j       kentry_exit                 # jump to kentry_exit
    217297    nop
    218298
    219299cause_sys:
    220         la          $1,         hal_do_syscall
    221         jalr    $1                          # call syscall handler                 
    222         addiu   $29,    $29,  -8            # hal_do_syscall has 2 args
    223         addiu   $29,    $29,  8
     300        jal     hal_do_syscall              # call syscall handler                 
     301    nop
    224302        j           kentry_exit                 # jump to kentry_exit
    225303        nop
    226304       
    227305cause_int:
    228         la          $1,     hal_do_interrupt
    229         jalr    $1                          # call interrupt handler
    230         addiu   $29,    $29,  -8            # hal_do_interrupt has 2 args
    231         addiu   $29,    $29,  8
     306        jal     hal_do_interrupt            # call interrupt handler
     307    nop
    232308
    233309# -----------------------------------------------------------------------------------
    234310# Kernel exit
    235 # The pointer on uzone is supposed to be stored in $19
     311# The pointer on uzone is supposed to be contained in $29
    236312# -----------------------------------------------------------------------------------
    237313kentry_exit:
    238314
     315#if CONFIG_KENTRY_DEBUG
     316
     317    # display "exit" message
     318    la      $4,     msg_exit
     319    jal     puts
     320    nop
     321    move    $4,     $29
     322    jal     putx
     323    nop
     324    la      $4,     msg_crlf
     325    jal     puts
     326    nop   
     327    # display saved SP value
     328    la      $4,     msg_sp
     329    jal     puts
     330    nop
     331    lw      $4,         (UZ_SP*4)($29)
     332    jal     putx
     333    nop
     334    la      $4,     msg_crlf
     335    jal     puts
     336    nop   
     337    # display saved RA value
     338    la      $4,     msg_ra
     339    jal     puts
     340    nop
     341    lw      $4,         (UZ_RA*4)($29)
     342    jal     putx
     343    nop
     344    la      $4,     msg_crlf
     345    jal     puts
     346    nop   
     347    # display saved TH value
     348    la      $4,     msg_th
     349    jal     puts
     350    nop
     351    lw      $4,         (UZ_TH*4)($29)
     352    jal     putx
     353    nop
     354    la      $4,     msg_crlf
     355    jal     puts
     356    nop   
     357    # display saved EPC value
     358    la      $4,     msg_epc
     359    jal     puts
     360    nop
     361    lw      $4,         (UZ_EPC*4)($29)
     362    jal     putx
     363    nop
     364    la      $4,     msg_crlf
     365    jal     puts
     366    nop   
     367    # display saved MODE value
     368    la      $4,     msg_mode
     369    jal     puts
     370    nop
     371    lw      $4,         (UZ_MODE*4)($29)
     372    jal     putx
     373    nop
     374    la      $4,     msg_crlf
     375    jal     puts
     376    nop   
     377    # display saved V0 value
     378    la      $4,     msg_v0
     379    jal     puts
     380    nop
     381    lw      $4,         (UZ_V0*4)($29)
     382    jal     putx
     383    nop
     384    la      $4,     msg_crlf
     385    jal     puts
     386    nop   
     387       
     388#endif
     389   
    239390        # restore registers from uzone
    240         or          $27,    $0, $19             # $27 <= &uzone
    241 
    242         lw          $29,        (UZ_SP*4)($27)          # restore SP from uzone
    243         lw          $16,        (UZ_EPC*4)($27)       
    244         mtc0    $16,    $14                             # restore EPC from uzone
    245         lw          $16,    (UZ_HI*4)($27)
    246         mthi    $16                                         # restore HI from uzone
    247         lw          $16,    (UZ_LO*4)($27)
    248         mtlo    $16                                         # restore LO from uzone
    249 
    250         lw          $17,        (UZ_SR*4)($27)          # get saved SR value from uzone
    251         andi    $17,    $17,    0x1F        # keep only the 5 LSB bits
    252         mfc0    $26,    $12                             # get current SR value from CP0
    253         or          $26,    $26,        $17         # merge the two values
    254         mtc0    $26,    $12                             # setup new SR to CP0
     391        or          $27,    $0, $29             # $27 <= ksp (contains &uzone)
     392
     393        lw          $1,     (UZ_EPC*4)($27)           
     394        mtc0    $1,         $14                         # restore c0_epc from uzone
     395        lw          $1,     (UZ_SR*4)($27)
     396        mtc0    $1,     $12                             # restore c0_sr from uzone
     397
     398        lw          $26,    (UZ_HI*4)($27)
     399        mthi    $26                                         # restore hi from uzone
     400        lw          $26,    (UZ_LO*4)($27)
     401        mtlo    $26                                         # restore lo from uzone
    255402
    256403        lw          $1,     (UZ_AT*4)($27)             
    257         lw          $2,     (UZ_V0*4)($27)
    258         lw          $3,     (UZ_V1*4)($27)
     404    lw      $2,     (UZ_V0*4)($27)
     405    lw      $3,     (UZ_V1*4)($27)
    259406        lw          $4,     (UZ_A0*4)($27)
    260407        lw          $5,     (UZ_A1*4)($27)
     
    279426        lw          $24,    (UZ_T8*4)($27)
    280427        lw          $25,    (UZ_T9*4)($27)     
    281         lw          $28,        (UZ_GP*4)($27)
    282         lw          $30,        (UZ_S8*4)($27)
    283         lw          $31,        (UZ_RA*4)($27)
     428
     429        lw          $28,        (UZ_GP*4)($27)      # restore gp_28 from uzone
     430        lw          $29,        (UZ_SP*4)($27)          # restore sp_29 from uzone
     431        lw          $30,        (UZ_S8*4)($27)      # restore s8_30 from uzone
     432        lw          $31,        (UZ_RA*4)($27)      # restore ra_31 from uzone
    284433
    285434        lw          $26,    (UZ_MODE*4)($27)   
     
    291440
    292441hal_kentry_eret:
    293         nop
    294     eret
     442    eret                                # jump to EPC, reset EXL bit
    295443
    296444    .set reorder
     
    298446
    299447#------------------------------------------------------------------------------------
    300 
     448    .section .kdata
     449
     450msg_sp:
     451    .align 2
     452    .asciiz "- UZ_SP   = "
     453msg_ra:
     454    .align 2
     455    .asciiz "- UZ_RA   = "
     456msg_epc:
     457    .align 2
     458    .asciiz "- UZ_EPC  = "
     459msg_th:
     460    .align 2
     461    .asciiz "- UZ_TH   = "
     462msg_mode:
     463    .align 2
     464    .asciiz "- UZ_MODE = "
     465msg_v0:
     466    .align 2
     467    .asciiz "- UZ_V0   = "
     468msg_crlf:
     469    .align 2
     470    .asciiz "\n"
     471msg_enter:
     472    .align 2
     473    .asciiz "\nenter kernel : &uzone = "
     474msg_exit:
     475    .align 2
     476    .asciiz "\nexit kernel : &uzone = "
     477
  • trunk/hal/tsar_mips32/core/hal_kentry.h

    r407 r408  
    3636
    3737/****************************************************************************************
    38  * This structure defines the cpu_uzone for TSAR MIPS32, as well as the
    39  *  mnemonics used by the hal_kentry assembly code.
     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.
     40 * WARNING : It is replicated in hal_kentry.S file.
    4041 ***************************************************************************************/
    4142
     
    5657#define      UZ_T6           14   /* t6_14   */
    5758#define      UZ_T7           15   /* t7_15   */
    58 #define      UZ_T8           16   /* t8_24   */
    59 #define      UZ_T9           17   /* t9_25   */
    60 #define      UZ_S0           18   /* s0_16   */
    61 #define      UZ_S1           19   /* s1_17   */
    62 #define      UZ_S2           20   /* s2_18   */
    63 #define      UZ_S3           21   /* s3_19   */
    64 #define      UZ_S4           22   /* s4_20   */
    65 #define      UZ_S5           23   /* s5_21   */
    66 #define      UZ_S6           24   /* s6_22   */
    67 #define      UZ_S7           25   /* s7_23   */
    68 #define      UZ_S8           26   /* s8_30   */
    69 #define      UZ_GP           27   /* gp_28   */
    70 #define      UZ_RA           28   /* ra_31   */
    71 #define      UZ_EPC          29   /* c0_epc  */
    72 #define      UZ_CR           30   /* c0_cr   */
    73 #define      UZ_SP           31   /* sp_29   */
    74 #define      UZ_SR           32   /* c0_sr   */
    75 #define      UZ_LO           33
    76 #define      UZ_HI           34
     59#define      UZ_S0           16   /* s0_16   */
     60#define      UZ_S1           17   /* s1_17   */
     61#define      UZ_S2           18   /* s2_18   */
     62#define      UZ_S3           19   /* s3_19   */
     63#define      UZ_S4           20   /* s4_20   */
     64#define      UZ_S5           21   /* s5_21   */
     65#define      UZ_S6           22   /* s6_22   */
     66#define      UZ_S7           23   /* s7_23   */
     67#define      UZ_T8           24   /* t8_24   */
     68#define      UZ_T9           25   /* t9_25   */
    7769
    78 #define      UZ_REGS         35
     70#define      UZ_LO           26
     71#define      UZ_HI           27
     72
     73#define      UZ_GP           28   /* gp_28   */
     74#define      UZ_SP           29   /* sp_29   */
     75#define      UZ_S8           30   /* s8_30   */
     76#define      UZ_RA           31   /* ra_31   */
     77
     78#define      UZ_PTPR         32   /* c2_ptpr */
     79#define      UZ_EPC          33   /* c0_epc  */
     80#define      UZ_SR           34   /* c0_sr   */
     81#define      UZ_TH           35   /* c0_th   */
     82#define      UZ_CR           36   /* c0_cr   */
     83
     84#define      UZ_REGS         37
    7985
    8086/*************************************************************************************
    8187 * The hal_kentry_enter() function is the unique kernel entry point in case of
    8288 * 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).
    8391 *
    84  * When we enter the kernel, we test the status register:
    85  * - If the core is in user mode, we desactivate the MMU, and we save
    86  *   the core context in the uzone of the calling thread descriptor.
    87  * - If the core is already in kernel mode (in case of interrupt),
    88  *   we save the context in the kernel stack.
    89  * - In both cases, we increment the cores_in_kernel variable,
    90  *   and we call the relevant exception/interrupt/syscall handler
     92 * In both cases it allocates an "uzone" space in the kernel stack to save the
     93 * CPU registers values, desactivates the MMU, and calls the relevant handler
     94 * (exception/interrupt/syscall)
    9195 *
    92  * When we exit the kernel after handler execution:
    93  * - we restore the core context from the uzone and return to user space,
    94  *   calling the hal_kentry_eret()
     96 * After handler execution, it restores the CPU context from the uzone and jumps
     97 * to address contained in EPC calling hal_kentry_eret()
    9598 ************************************************************************************/
    9699void hal_kentry_enter();
     
    98101/*************************************************************************************
    99102 * The hal_kentry_eret() function contains only the assembly "eret" instruction,
    100  * that and the EXL bit in the c0_sr register, and jump to the address
     103 * that reset the EXL bit in the c0_sr register, and jump to the address
    101104 * contained in the c0_epc register.
    102105 * ************************************************************************************/
  • trunk/hal/tsar_mips32/core/hal_switch.S

    r407 r408  
    3737hal_do_cpu_switch:
    3838
     39    /* save old thread context */
     40 
    3941    move    $26,   $4                  /* $26 <= ctx_old */
    4042
     
    4951    sw      $6,    6*4($26)         
    5052    sw      $7,    7*4($26)         
    51 
    5253    sw      $8,    8*4($26)         
    5354    sw      $9,    9*4($26)         
     
    5859    sw      $14,  14*4($26)         
    5960    sw      $15,  15*4($26)         
    60 
    6161    sw      $16,  16*4($26)         
    6262    sw      $17,  17*4($26)         
     
    6767    sw      $22,  22*4($26)         
    6868    sw      $23,  23*4($26)         
    69 
    7069    sw      $24,  24*4($26)         
    7170    sw      $25,  25*4($26)         
     
    9190        sw      $27,  33*4($26)           /* save c2_mode to slot 33 */
    9291
    93     sync                           
    94 
     92    /* restore new thread context */
     93 
    9594    move    $26,   $5                  /* $26 <= ctx_new */
    9695
     
    105104    lw      $6,    6*4($26)         
    106105    lw      $7,    7*4($26)         
    107 
    108106    lw      $8,    8*4($26)         
    109107    lw      $9,    9*4($26)         
     
    114112    lw      $14,  14*4($26)         
    115113    lw      $15,  15*4($26)         
    116 
    117114        lw      $16,  16*4($26)         
    118115        lw      $17,  17*4($26)         
     
    123120    lw      $22,  22*4($26)         
    124121    lw      $23,  23*4($26)         
    125 
    126122    lw      $24,  24*4($26)         
    127123    lw      $25,  25*4($26)         
     
    149145    mtc0        $26,  $12                  /* restore c0_sr from slot 34 */
    150146
     147    sync                           
     148
    151149    jr      $31                        /* return to caller */
    152150    nop
    153151
    154152#---------------------------------------------------------------------------------
    155 # The hal_do_cpu_save()function makes the following assumptions:
     153# The hal_do_cpu_save()function makes the following assumption:
    156154# - register $4 contains a pointer on the target thread context.
    157 # - register $5 contains the target thread descriptor pointer.
    158 # - register $6 contains the offset to add to stack pointer.
    159155#---------------------------------------------------------------------------------
    160156hal_do_cpu_save:
    161157
    162     move    $26,  $4                  /* $26 <= context */
    163 
    164     move    $27,  $5
    165         sw      $27,  35*4($26)           /* save child thread to slot 35 */
    166 
    167     add     $27,  $6,  $29
    168     sw      $27,  29*4($26)           /* save (sp_29 + offset) to slot 29 */
    169 
    170     mfc0    $27,  $12               
    171         sw      $27,  34*4($26)           /* save c0_sr to slot 34 */
    172 
    173         mfc2    $27,  $0               
    174         sw      $27,  32*4($26)           /* save c2_ptpr to slot 32 */
    175 
    176         mfc2    $27,  $1               
    177         sw      $27,  33*4($26)           /* save c2_mode to slot 33 */
    178 
    179     mfc0    $27,   $14             
     158    move    $26,  $4                  /* $26 <= &context */
     159
     160    mfc0    $27,  $14               
    180161    sw      $27,   0*4($26)           /* save c0_epc to slot 0 */
    181  
     162
    182163    sw      $1,    1*4($26)         
    183164    sw      $2,    2*4($26)         
     
    187168    sw      $6,    6*4($26)         
    188169    sw      $7,    7*4($26)         
    189 
    190170    sw      $8,    8*4($26)         
    191171    sw      $9,    9*4($26)         
     
    196176    sw      $14,  14*4($26)         
    197177    sw      $15,  15*4($26)         
    198 
    199178    sw      $16,  16*4($26)         
    200179    sw      $17,  17*4($26)         
     
    205184    sw      $22,  22*4($26)         
    206185    sw      $23,  23*4($26)         
    207 
    208186    sw      $24,  24*4($26)         
    209     sw      $25,  25*4($26)         
    210 
     187    sw      $25,  25*4($26)
     188         
    211189    mfhi    $27                     
    212     sw      $27,  26*4($26)           /* save hi to slot 26 */
    213 
     190    sw      $27,  26*4($26)           /* save hi      to slot 26 */
    214191    mflo    $27                     
    215     sw      $27,  27*4($26)           /* save lo to slot 27 */
    216 
    217     sw      $28,  28*4($26)           /* save gp to slot 28 */
    218 
    219     sw      $30,  30*4($26)           /* save s8 to slot 30 */
    220     sw      $31,  31*4($26)           /* save ra to slot 31 */
     192    sw      $27,  27*4($26)           /* save lo      to slot 27 */
     193
     194    sw      $28,  28*4($26)           /* save gp      to slot 28 */
     195    sw      $29,  29*4($26)           /* save sp      to slot 29 */
     196    sw      $30,  30*4($26)           /* save s8      to slot 30 */
     197    sw      $31,  31*4($26)           /* save ra      to slot 31 */
     198
     199        mfc2    $27,  $0               
     200        sw      $27,  32*4($26)           /* save c2_ptpr to slot 32 */
     201        mfc2    $27,  $1               
     202        sw      $27,  33*4($26)           /* save c2_mode to slot 33 */
     203    mfc0    $27,  $12             
     204        sw      $27,  34*4($26)           /* save c0_sr   to slot 34 */
     205    mfc0    $27,  $4, 2             
     206        sw      $27,  35*4($26)           /* save c0_th   to slot 35 */
    221207
    222208    sync
  • trunk/hal/tsar_mips32/core/hal_syscall.c

    r407 r408  
    3030
    3131
    32 /////////////////////////////////////
    33 void hal_do_syscall( thread_t * this,
    34                      reg_t    * regs_tbl )
     32/////////////////////
     33void hal_do_syscall()
    3534{
     35    thread_t    * this;
    3636
    37 #if(CONFIG_SYSCALL_DEBUG & 0x1)
    38 printk("\n[DBG] %s : core[%x,%d] enter at cycle %d\n",
    39 __FUNCTION__ , local_cxy , this->core->lid , hal_time_stamp() );
    40 #endif
     37    uint32_t    * enter_uzone;
     38    uint32_t    * exit_uzone;
    4139
    42         register reg_t      arg0;
    43         register reg_t      arg1;
    44         register reg_t      arg2;
    45         register reg_t      arg3;
    46         register reg_t      service_num;
    47         register reg_t      retval;
     40        uint32_t      arg0;
     41        uint32_t      arg1;
     42        uint32_t      arg2;
     43        uint32_t      arg3;
     44        uint32_t      service_num;
     45        uint32_t      retval;
    4846 
    49         service_num = regs_tbl[UZ_V0];
     47    // get pointer on enter_thread uzone
     48    this        = CURRENT_THREAD;
     49    enter_uzone = (uint32_t *)this->uzone;
    5050
    51         arg0        = regs_tbl[UZ_A0];
    52         arg1        = regs_tbl[UZ_A1];
    53         arg2        = regs_tbl[UZ_A2];
    54         arg3        = regs_tbl[UZ_A3];
     51    // get syscall arguments from uzone
     52        service_num = enter_uzone[UZ_V0];
     53        arg0        = enter_uzone[UZ_A0];
     54        arg1        = enter_uzone[UZ_A1];
     55        arg2        = enter_uzone[UZ_A2];
     56        arg3        = enter_uzone[UZ_A3];
    5557 
     58syscall_dmsg("\n[DBG] %s : core[%x,%d] enters for %s / &uzone %x / cycle %d \n",
     59__FUNCTION__, local_cxy, this->core->lid,
     60syscall_str(service_num) , enter_uzone , (uint32_t)hal_get_cycles() );
     61
    5662    // call architecture independant syscall handler
    5763        retval = do_syscall( this,
     
    6268                         service_num );
    6369
    64         regs_tbl[UZ_V0]   = retval;
    65         regs_tbl[UZ_V1]   = this->errno;
    66         regs_tbl[UZ_EPC] += 4;
     70    // get pointer on exit_thread uzone,
     71    // exit_thread can be different from enter_thread
     72    this       = CURRENT_THREAD;
     73    exit_uzone = (uint32_t *)this->uzone;
    6774
    68 #if(CONFIG_SYSCALL_DEBUG & 0x1)
    69 printk("\n[DBG] %s : core[%x,%d] exit at cycle %d\n",
    70 __FUNCTION__ , local_cxy , this->core->lid , hal_time_stamp() );
    71 #endif
     75    // set syscall return value to uzone
     76        exit_uzone[UZ_V0] = retval;
     77
     78    // update EPC in uzone
     79        exit_uzone[UZ_EPC] += 4;
     80
     81syscall_dmsg("\n[DBG] %s : core[%x,%d] exit from %s / &uzone %x / cycle %d \n",
     82__FUNCTION__, local_cxy, this->core->lid,
     83syscall_str(service_num) , exit_uzone , (uint32_t)hal_get_cycles() );
    7284
    7385}
  • trunk/hal/tsar_mips32/core/hal_types.h

    r407 r408  
    134134 *  Address types and macros         !!!  hardware dependant  !!!
    135135 ***************************************************************************
    136  * An extended pointer a 64 bits integer, structured in two fields :
     136 * An extended pointer is a 64 bits integer, structured in two fields :
    137137 * - cxy : cluster identifier.
    138138 * - ptr : pointer in the virtual space of a single cluster.
Note: See TracChangeset for help on using the changeset viewer.