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

First implementation of fork/exec.

File:
1 edited

Legend:

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

    r406 r407  
    5858
    5959//////////////////////////////////////////////////////////////////////////////////////////
    60 // This enum defines the mask valuesi for an MMU exception code reported by the mips32.
     60// This enum defines the mask values for an MMU exception code reported by the mips32.
    6161//////////////////////////////////////////////////////////////////////////////////////////
    6262
    6363typedef enum
    6464{
    65     MMU_EXCP_PAGE_UNMAPPED   = 0x0003,
    66     MMU_EXCP_USER_PRIVILEGE  = 0x0004,
    67     MMU_EXCP_USER_WRITE      = 0x0008,
    68     MMU_EXCP_USER_EXEC       = 0x1010,
     65    MMU_WRITE_PT1_UNMAPPED        = 0x0001,
     66    MMU_WRITE_PT2_UNMAPPED        = 0x0002,
     67    MMU_WRITE_PRIVILEGE_VIOLATION = 0x0004,
     68    MMU_WRITE_ACCESS_VIOLATION    = 0x0008,
     69    MMU_WRITE_UNDEFINED_XTN       = 0x0020,
     70    MMU_WRITE_PT1_ILLEGAL_ACCESS  = 0x0040,
     71    MMU_WRITE_PT2_ILLEGAL_ACCESS  = 0x0080,
     72    MMU_WRITE_DATA_ILLEGAL_ACCESS = 0x0100,
     73
     74    MMU_READ_PT1_UNMAPPED         = 0x1001,
     75    MMU_READ_PT2_UNMAPPED         = 0x1002,
     76    MMU_READ_PRIVILEGE_VIOLATION  = 0x1004,
     77    MMU_READ_EXEC_VIOLATION       = 0x1010,
     78    MMU_READ_UNDEFINED_XTN        = 0x1020,
     79    MMU_READ_PT1_ILLEGAL_ACCESS   = 0x1040,
     80    MMU_READ_PT2_ILLEGAL_ACCESS   = 0x1080,
     81    MMU_READ_DATA_ILLEGAL_ACCESS  = 0x1100,
    6982}
    7083mmu_exception_subtype_t;
     
    148161    process = this->process;
    149162
    150     excp_dmsg("\n[DMSG] %s : enter for thread %x in process %x / is_ins = %d\n",
    151     __FUNCTION__ , this->trdid , process->pid , is_ins );
    152 
    153163    // get relevant values from MMU
    154164        hal_get_mmu_excp( &mmu_ins_excp_code,
     
    157167                          &mmu_dat_bad_vaddr );
    158168
    159     excp_dmsg("\n[DMSG] %s : icode = %x / ivaddr = %x / dcode = %x / dvaddr = %x\n",
    160     __FUNCTION__ , mmu_ins_excp_code , mmu_ins_bad_vaddr ,
    161                    mmu_dat_excp_code , mmu_dat_bad_vaddr );
    162 
    163169    // get exception code and faulty vaddr, depending on IBE/DBE
    164170    if( is_ins )
     
    173179    }
    174180
    175     excp_dmsg("\n[DMSG] %s : excp_code = %x / bad_vaddr = %x\n",
    176     __FUNCTION__ , excp_code , bad_vaddr );
    177 
    178     // analyse exception code
    179     if( excp_code & MMU_EXCP_PAGE_UNMAPPED )
    180     {
    181         excp_dmsg("\n[DMSG] %s : type PAGE_UNMAPPED\n", __FUNCTION__ );
    182 
    183         // enable IRQs before handling page fault
    184         // hal_enable_irq( NULL );
    185 
    186         // try to map the unmapped PTE
    187         error = vmm_handle_page_fault( process,
    188                                        bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );  // vpn
    189         // disable IRQs
    190         // hal_disable_irq( NULL );
    191 
    192         if( error )     // not enough memory
    193         {
    194             printk("\n[ERROR] in %s for thread %x : cannot map vaddr = %x\n",
    195                __FUNCTION__ , this->trdid , bad_vaddr );
    196 
    197                     return EXCP_USER_ERROR;
    198         }
    199         else            // page fault successfully handled
    200         {
    201             excp_dmsg("\n[DMSG] %s : page fault handled / bad_vaddr = %x / excp_code = %x\n",
    202                              __FUNCTION__ , bad_vaddr , excp_code );
     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 );
     183
     184   // analyse exception code
     185    switch( excp_code )
     186    {
     187        case MMU_WRITE_PT1_UNMAPPED:      // non fatal
     188        case MMU_WRITE_PT2_UNMAPPED:
     189        case MMU_READ_PT1_UNMAPPED:
     190        case MMU_READ_PT2_UNMAPPED:
     191        {
     192            // try to map the unmapped PTE
     193            error = vmm_handle_page_fault( process,
     194                                           bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );  // vpn
     195            if( error )   
     196            {
     197                printk("\n[ERROR] in %s for thread %x : cannot map vaddr = %x\n",
     198                __FUNCTION__ , this->trdid , bad_vaddr );
     199
     200                        return EXCP_USER_ERROR;
     201            }
     202            else            // page fault successfull
     203            {
     204
     205excp_dmsg("\n[DBG] %s : core[%x,%d] / page-fault handled for vaddr = %x\n",
     206__FUNCTION__ , local_cxy , this->core->lid , bad_vaddr );
    203207 
    204             return EXCP_NON_FATAL;
    205         }
    206     }
    207     else if( excp_code & MMU_EXCP_USER_PRIVILEGE )
    208     {
    209         printk("\n[ERROR] in %s for thread %x : user access to kernel vseg at vaddr = %x\n",
    210                __FUNCTION__ , this->trdid , bad_vaddr );
    211 
    212         return EXCP_USER_ERROR;
    213     }
    214     else if( excp_code & MMU_EXCP_USER_EXEC )
    215     {
    216         printk("\n[ERROR] in %s for thread %x : access to non-exec vseg at vaddr = %x\n",
    217                __FUNCTION__ , this->trdid , bad_vaddr );
    218 
    219         return EXCP_USER_ERROR;
    220     }
    221     else if( excp_code & MMU_EXCP_USER_WRITE )
    222     {
    223         printk("\n[ERROR] in %s for thread %x : write to non-writable vseg at vaddr = %x\n",
    224                __FUNCTION__ , this->trdid , bad_vaddr );
    225 
    226         return EXCP_USER_ERROR;
    227     }
    228     else  // this is a kernel error => panic   
    229     {
    230         printk("\n[PANIC] in %s for thread %x : kernel exception = %x / vaddr = %x\n",
    231                __FUNCTION__ , this->trdid , excp_code , bad_vaddr );
    232 
    233         return EXCP_KERNEL_PANIC;
    234     }
    235  
     208                return EXCP_NON_FATAL;
     209            }
     210        }
     211        case MMU_WRITE_PRIVILEGE_VIOLATION:  // illegal access user error
     212        case MMU_READ_PRIVILEGE_VIOLATION:
     213        {
     214            printk("\n[ERROR] in %s for thread %x : illegal user access to vaddr = %x\n",
     215            __FUNCTION__ , this->trdid , bad_vaddr );
     216
     217            return EXCP_USER_ERROR;
     218        }
     219        case MMU_WRITE_ACCESS_VIOLATION:     // user error or Copy-on-Write
     220        {
     221            // access page table to get GPT_COW flag
     222            bool_t cow = hal_gpt_pte_is_cow( &(process->vmm.gpt),
     223                                             bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );  // vpn
     224
     225            if( cow )                        // Copy-on-Write
     226            {
     227                // try to allocate and copy the page
     228                error = vmm_copy_on_write( process,
     229                                           bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );  // vpn
     230                if( error )
     231                {
     232                    printk("\n[ERROR] in %s for thread %x : cannot cow vaddr = %x\n",
     233                    __FUNCTION__ , this->trdid , bad_vaddr );
     234
     235                            return EXCP_USER_ERROR;
     236                }
     237                else         // Copy on write successfull
     238                {
     239
     240excp_dmsg("\n[DBG] %s : core[%x,%d] / copy-on-write handled for vaddr = %x\n",
     241__FUNCTION__ , local_cxy , this->core->lid , bad_vaddr );
     242
     243                    return EXCP_NON_FATAL;
     244                }
     245            }
     246            else                             // non writable user error
     247            {
     248                printk("\n[ERROR] in %s for thread %x : write to non-writable vaddr = %x\n",
     249                __FUNCTION__ , this->trdid , bad_vaddr );
     250
     251                return EXCP_USER_ERROR;
     252            }
     253        }
     254        case MMU_READ_EXEC_VIOLATION:        // user error
     255        {
     256            printk("\n[ERROR] in %s for thread %x : read to non-executable vaddr = %x\n",
     257            __FUNCTION__ , this->trdid , bad_vaddr );
     258
     259            return EXCP_USER_ERROR;
     260        }
     261        default:                             // this is a kernel error => panic   
     262        {
     263            printk("\n[PANIC] in %s for thread %x : kernel exception = %x / vaddr = %x\n",
     264            __FUNCTION__ , this->trdid , excp_code , bad_vaddr );
     265
     266            return EXCP_KERNEL_PANIC;
     267        }
     268    } 
    236269} // end hal_mmu_exception()
    237270
     
    242275// @ this     : pointer on faulty thread descriptor.
    243276// @ regs_tbl : pointer on register array.
    244 // @ return always EXCP_NON_FATAL
     277// @ error    : EXCP_USER_ERROR or EXCP_KERNEL_PANIC
    245278//////////////////////////////////////////////////////////////////////////////////////////
    246279static void hal_exception_dump( thread_t * this,
    247                                 reg_t    * regs_tbl )
     280                                reg_t    * regs_tbl,
     281                                error_t    error )
    248282{
    249283    uint32_t  save_sr;
     284    core_t  * core = this->core;
    250285
    251286    // get pointers on TXT0 chdev
    252     xptr_t    txt0_xp  = chdev_dir.txt[0];
     287    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
    253288    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
    254289    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     
    260295    remote_spinlock_lock_busy( lock_xp , &save_sr );
    261296
    262     if( this->type == THREAD_USER )
    263     nolock_printk("\n================= USER ERROR / cycle %d ====================\n",
    264            hal_time_stamp() );
     297    if( error == EXCP_USER_ERROR )
     298    {
     299        nolock_printk("\n========= USER ERROR / core[%x,%d] / cycle %d ==============\n",
     300        local_cxy , core->lid , (uint32_t)hal_get_cycles() );
     301    }
    265302    else
    266     nolock_printk("\n================= KERNEL PANIC / cycle %d ==================\n",
    267            hal_time_stamp() );
     303    {
     304        nolock_printk("\n======= KERNEL PANIC / core[%x,%d] / cycle %d ==============\n",
     305        local_cxy , core->lid , (uint32_t)hal_get_cycles() );
     306    }
    268307
    269308        nolock_printk("  thread type = %s / trdid = %x / pid %x / core[%x,%d]\n"
     
    272311           this->core->lid, this->local_locks, this->remote_locks, this->blocked );
    273312
    274         nolock_printk("CR    %X  EPC   %X  SR    %X  SP    %X\n",
    275                    regs_tbl[UZ_CR], regs_tbl[UZ_EPC], regs_tbl[UZ_SR], regs_tbl[UZ_SP]);
    276 
    277     nolock_printk("at_1 %X  v0_2  %X  v1_3  %X  a0_4   %X  a1_5   %X\n",
    278                regs_tbl[UZ_AT], regs_tbl[UZ_V0], regs_tbl[UZ_V1], regs_tbl[UZ_A0], regs_tbl[UZ_A1]);
     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]);
    279318
    280319    nolock_printk("a2_6  %X  a3_7  %X  t0_8  %X  t1_9   %X  t2_10  %X\n",
     
    284323                   regs_tbl[UZ_T3],regs_tbl[UZ_T4],regs_tbl[UZ_T5],regs_tbl[UZ_T6],regs_tbl[UZ_T7]);
    285324
    286     nolock_printk("t8_24 %X  t9_25 %X  gp_28 %X  c0_hi  %X  c0_lo  %X\n",
    287                    regs_tbl[UZ_T8],regs_tbl[UZ_T9],regs_tbl[UZ_GP],regs_tbl[UZ_HI],regs_tbl[UZ_LO]);
    288 
    289325    nolock_printk("s0_16 %X  s1_17 %X  s2_18 %X  s3_19  %X  s4_20  %X\n",
    290326                   regs_tbl[UZ_S0],regs_tbl[UZ_S1],regs_tbl[UZ_S2],regs_tbl[UZ_S3],regs_tbl[UZ_S4]);
    291327 
    292     nolock_printk("s5_21 %X  s6_22 %X  s7_23 %X  s8_30  %X  ra_31  %X\n",
    293                regs_tbl[UZ_S5],regs_tbl[UZ_S6],regs_tbl[UZ_S7],regs_tbl[UZ_S8],regs_tbl[UZ_RA]);
     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]);
    294333
    295334    // release the lock
     
    311350        excCode        = (regs_tbl[UZ_CR] >> 2) & 0xF;
    312351
    313     excp_dmsg("\n[DMSG] %s : enter for thread %x in process %x / xcode = %x / cycle %d\n",
    314     __FUNCTION__ , this->trdid , this->process->pid , excCode , hal_time_stamp() );
     352excp_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / xcode %x / cycle %d\n",
     353__FUNCTION__, local_cxy, this->core->lid, this->trdid,
     354this->process->pid, excCode, (uint32_t)hal_get_cycle() );
    315355
    316356        switch(excCode)
     
    355395        if( error == EXCP_USER_ERROR )          //  user error => kill user process
    356396        {
    357         hal_exception_dump( this , regs_tbl );
    358         sys_kill( this->process->pid , SIGKILL );
     397        hal_exception_dump( this , regs_tbl , error );
     398
     399        // FIXME : replace this loop by sys_kill()
     400        while( 1 ) asm volatile ("nop");
     401        // sys_kill( this->process->pid , SIGKILL );
    359402        }
    360403    else if( error == EXCP_KERNEL_PANIC )   // kernel error => kernel panic
    361404    {
    362         hal_exception_dump( this , regs_tbl );
     405        hal_exception_dump( this , regs_tbl , error );
    363406        hal_core_sleep();
    364407    }
    365408
    366     excp_dmsg("\n[DMSG] %s : exit for thread %x in process %x / cycle %d\n",
    367     __FUNCTION__ , this->trdid , this->process->pid , hal_time_stamp() );
     409excp_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() );
    368411
    369412}  // end hal_do_exception()
Note: See TracChangeset for help on using the changeset viewer.