Ignore:
Timestamp:
Aug 24, 2015, 5:08:30 PM (9 years ago)
Author:
guerin
Message:

fix kill/exec

  • introduce physical_memcpy for fat_read
  • don't defer task exec
  • load writable segments in exec syscall
File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_kernel/sys_handler.c

    r700 r707  
    1515#include <ctx_handler.h>
    1616#include <fat32.h>
     17#include <elf-types.h>
    1718#include <utils.h>
    1819#include <kernel_malloc.h>
     
    172173
    173174    &_fat_open,                      /* 0x20 */
    174     &_fat_read,                      /* 0x21 */
     175    &_sys_fat_read,                  /* 0x21 */
    175176    &_fat_write,                     /* 0x22 */
    176177    &_fat_lseek,                     /* 0x23 */
     
    206207};
    207208
     209////////////////////////////////////////////////////////////////////////
     210static unsigned int _load_writable_segments( mapping_vspace_t*  vspace )
     211{
     212#if GIET_DEBUG_SWITCH
     213unsigned int gpid       = _get_procid();
     214unsigned int cluster_xy = gpid >> P_WIDTH;
     215unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     216unsigned int x          = cluster_xy >> Y_WIDTH;
     217unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
     218if ( _get_proctime() > GIET_DEBUG_SWITCH )
     219_printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : enters for %s\n",
     220        x , y , p , vspace->name );
     221#endif
     222
     223    mapping_header_t*  header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     224    mapping_vseg_t*    vseg    = _get_vseg_base(header);
     225
     226    // buffer to store one cluster
     227    char  buf[4096];
     228
     229    // open the .elf file associated to vspace
     230    unsigned int      vseg_id;
     231    unsigned int      fd = 0;
     232
     233    for (vseg_id = vspace->vseg_offset;
     234         vseg_id < (vspace->vseg_offset + vspace->vsegs);
     235         vseg_id++)
     236    {
     237        if(vseg[vseg_id].type == VSEG_TYPE_ELF)
     238        {
     239            fd = _fat_open( vseg[vseg_id].binpath , O_RDONLY );
     240
     241#if GIET_DEBUG_SWITCH
     242if ( _get_proctime() > GIET_DEBUG_SWITCH )
     243_printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : open %s / fd = %d\n",
     244        x , y , p , vseg[vseg_id].binpath , fd );
     245#endif
     246
     247            if ( fd < 0 ) return 1;
     248            break;
     249        }
     250    }
     251
     252    // load Elf-Header into buffer from .elf file
     253    if ( _fat_lseek( fd, 0, SEEK_SET ) < 0 ) return 1;
     254    if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) return 1;
     255
     256#if GIET_DEBUG_SWITCH
     257if ( _get_proctime() > GIET_DEBUG_SWITCH )
     258_printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : load Elf-Header\n",
     259        x , y , p );
     260#endif
     261
     262    // get nsegments and Program-Header-Table offset from Elf-Header
     263    Elf32_Ehdr*  elf_header_ptr = (Elf32_Ehdr*)buf;
     264    unsigned int offset         = elf_header_ptr->e_phoff;
     265    unsigned int nsegments      = elf_header_ptr->e_phnum;
     266
     267    // load Program-Header-Table from .elf file
     268    if ( _fat_lseek( fd, offset, SEEK_SET ) < 0 ) return 1;
     269    if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) return 1;
     270
     271#if GIET_DEBUG_SWITCH
     272if ( _get_proctime() > GIET_DEBUG_SWITCH )
     273_printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : "
     274        "load Program-Header-Table\n", x , y , p );
     275#endif
     276
     277    // set Program-Header-Table pointer
     278    Elf32_Phdr*  elf_pht_ptr = (Elf32_Phdr*)buf;
     279
     280    // scan segments to  load all loadable & writable segments
     281    unsigned int seg_id;
     282    for (seg_id = 0 ; seg_id < nsegments ; seg_id++)
     283    {
     284        if ( (elf_pht_ptr[seg_id].p_type == PT_LOAD) &&    // loadable
     285             (elf_pht_ptr[seg_id].p_flags & PF_W) )        // writable
     286        {
     287            // Get segment attributes
     288            paddr_t      seg_paddr  = vseg[vseg_id].pbase;
     289            unsigned int seg_offset = elf_pht_ptr[seg_id].p_offset;
     290            unsigned int seg_size   = elf_pht_ptr[seg_id].p_filesz;
     291
     292            // load the segment
     293            if ( _fat_lseek( fd, seg_offset, SEEK_SET ) < 0 ) return 1;
     294            if ( _fat_read( fd, seg_paddr, seg_size, 1 ) < 0 ) return 1;
     295
     296#if GIET_DEBUG_SWITCH
     297if ( _get_proctime() > GIET_DEBUG_SWITCH )
     298_printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : load segment %x\n",
     299        x , y , p , seg_vaddr );
     300#endif
     301        }
     302    }  // end loop on writable & loadable segments
     303
     304    // close .elf file
     305    _fat_close( fd );
     306
     307    return 0;
     308}  // end load_writable_segments()
    208309
    209310//////////////////////////////////////////////////////////////////////////////
     
    275376{
    276377    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     378    mapping_vseg_t   * vseg    = _get_vseg_base(header);
    277379    mapping_vspace_t * vspace  = _get_vspace_base(header);
    278380    mapping_task_t   * task    = _get_task_base(header);
     
    282384    unsigned int y_size = header->y_size;
    283385
    284 #if GIET_DEBUG_EXEC 
     386#if GIET_DEBUG_EXEC
    285387if ( _get_proctime() > GIET_DEBUG_EXEC )
    286388_printf("\n[DEBUG EXEC] enters _sys_exec_application() at cycle %d for %s\n",
     
    288390#endif
    289391
    290     // scan vspaces
    291     for (vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++)
    292     {
    293         if ( _strcmp( vspace[vspace_id].name, name ) == 0 )
     392    // find vspace
     393    for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
     394    {
     395        if ( _strcmp( vspace[vspace_id].name, name ) == 0 )
     396            break;
     397    }
     398
     399    if ( vspace_id == header->vspaces )
     400    {
     401        _printf("\n[GIET ERROR] _sys_exec_application() : %s not found\n", name );
     402        return -1;
     403    }
     404
     405    // scan tasks in vspace
     406    for (task_id = vspace[vspace_id].task_offset;
     407         task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
     408         task_id++)
     409    {
     410        unsigned int cid   = task[task_id].clusterid;
     411        unsigned int x     = cid / y_size;
     412        unsigned int y     = cid % y_size;
     413        unsigned int p     = task[task_id].proclocid;
     414        unsigned int ltid  = task[task_id].ltid;
     415
     416        // get scheduler pointer for processor running the task
     417        static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
     418
     419        // check if an application task is runnable
     420        if ( psched->context[ltid][CTX_NORUN_ID] == 0 )
    294421        {
    295             // scan tasks in vspace
    296             for (task_id = vspace[vspace_id].task_offset;
    297                  task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    298                  task_id++)
    299             {
    300                 unsigned int cid   = task[task_id].clusterid;
    301                 unsigned int x     = cid / y_size;
    302                 unsigned int y     = cid % y_size;
    303                 unsigned int p     = task[task_id].proclocid;
    304                 unsigned int ltid  = task[task_id].ltid;
    305 
    306                 // get scheduler pointer for processor running the task
    307                 static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    308 
    309                 // set EXEC signal bit
    310                 _atomic_or( &psched->context[ltid][CTX_SIG_ID] , SIG_MASK_EXEC );
    311             }
    312 
    313 #if GIET_DEBUG_EXEC
     422            _printf( "\n[GIET ERROR] _sys_exec_application() : %s already executed\n", name );
     423            return -2;
     424        }
     425    }
     426
     427    // reload writable segments
     428    if ( _load_writable_segments( &vspace[vspace_id] ) )
     429    {
     430         _printf("[GIET ERROR] _sys_exec_application() : can't load segments for %s\n", name );
     431         return -3;
     432    }
     433
     434    // scan tasks in vspace
     435    for (task_id = vspace[vspace_id].task_offset;
     436         task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
     437         task_id++)
     438    {
     439        unsigned int cid   = task[task_id].clusterid;
     440        unsigned int x     = cid / y_size;
     441        unsigned int y     = cid % y_size;
     442        unsigned int p     = task[task_id].proclocid;
     443        unsigned int ltid  = task[task_id].ltid;
     444
     445        // get scheduler pointer for processor running the task
     446        static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
     447
     448        // reset task context: RA / SR / SP / EPC / NORUN
     449        unsigned int vseg_id       = task[task_id].stack_vseg_id;
     450        unsigned int sp_value      = vseg[vseg_id].vbase + vseg[vseg_id].length;
     451
     452        psched->context[ltid][CTX_RA_ID]     = (unsigned int)&_ctx_eret;
     453        psched->context[ltid][CTX_SR_ID]     = GIET_SR_INIT_VALUE;
     454        psched->context[ltid][CTX_SP_ID]     = sp_value;
     455        psched->context[ltid][CTX_EPC_ID]    = psched->context[ltid][CTX_ENTRY_ID];
     456        psched->context[ltid][CTX_NORUN_ID]  = 0;
     457    }
     458
     459#if GIET_DEBUG_EXEC
    314460if ( _get_proctime() > GIET_DEBUG_EXEC )
    315461_printf("\n[DEBUG EXEC] exit _sys_exec_application() at cycle %d : %s will be executed\n",
     
    317463#endif
    318464
    319             return 0;   // application found and activated
    320         }
    321     }
    322 
    323 #if GIET_DEBUG_EXEC
    324 if ( _get_proctime() > GIET_DEBUG_EXEC )
    325 _printf("\n[DEBUG EXEC] exit _sys_exec_application() at cycle %d : %s not found\n",
    326          _get_proctime() , name );
    327 #endif
    328 
    329     return -1;    // not found
    330 
     465    return 0;
    331466}  // end _sys_exec_application()
    332467   
     
    487622 
    488623    // physical addresses
    489     unsigned long long buffer_paddr;
     624    paddr_t            buffer_paddr;
    490625    unsigned int       buffer_lsb;
    491626    unsigned int       buffer_msb;
    492     unsigned long long mwmr_paddr = 0;
     627    paddr_t            mwmr_paddr = 0;
    493628    unsigned int       mwmr_lsb;
    494629    unsigned int       mwmr_msb;
    495     unsigned long long lock_paddr = 0;
     630    paddr_t            lock_paddr = 0;
    496631    unsigned int       lock_lsb;
    497632    unsigned int       lock_msb;
     
    23562491}  // end _sys_tasks_status()
    23572492
     2493int _sys_fat_read( unsigned int fd_id,
     2494                   unsigned int buffer,
     2495                   unsigned int count )
     2496{
     2497    return _fat_read(fd_id, buffer, count, 0);
     2498}
     2499
    23582500
    23592501
Note: See TracChangeset for help on using the changeset viewer.