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
Location:
soft/giet_vm/giet_kernel
Files:
4 edited

Legend:

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

    r706 r707  
    1313#include <tty0.h>
    1414#include <xcu_driver.h>
    15 #include <fat32.h>
    16 #include <elf-types.h>
    1715
    1816/////////////////////////////////////////////////////////////////////////////////
     
    7977
    8078} // end _ctx_kill_task()
    81 
    82 
    83 
    84 ////////////////////////////////////////////////////////////////////////
    85 static unsigned int _load_writable_segments( mapping_vspace_t*  vspace )
    86 {
    87 
    88 #if GIET_DEBUG_SWITCH
    89 unsigned int gpid       = _get_procid();
    90 unsigned int cluster_xy = gpid >> P_WIDTH;
    91 unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    92 unsigned int x          = cluster_xy >> Y_WIDTH;
    93 unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    94 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    95 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : enters for %s\n",
    96         x , y , p , vspace->name );
    97 #endif
    98 
    99     mapping_header_t*  header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    100     mapping_vseg_t*    vseg    = _get_vseg_base(header);
    101 
    102     // buffer to store one cluster
    103     char  buf[4096];
    104 
    105     // open the .elf file associated to vspace
    106     unsigned int      vseg_id;
    107     unsigned int      fd = 0;
    108    
    109     for (vseg_id = vspace->vseg_offset;
    110          vseg_id < (vspace->vseg_offset + vspace->vsegs);
    111          vseg_id++)
    112     {
    113         if(vseg[vseg_id].type == VSEG_TYPE_ELF)
    114         {   
    115             fd = _fat_open( vseg[vseg_id].binpath , O_RDONLY );
    116 
    117 #if GIET_DEBUG_SWITCH
    118 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    119 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : open %s / fd = %d\n",
    120         x , y , p , vseg[vseg_id].binpath , fd );
    121 #endif
    122 
    123             if ( fd < 0 ) return 1;
    124             break;
    125         }
    126     }
    127 
    128     // load Elf-Header into buffer from .elf file
    129     if ( _fat_lseek( fd, 0, SEEK_SET ) < 0 ) return 1;
    130     if ( _fat_read( fd, buf, 4096 ) < 0 ) return 1;
    131 
    132 #if GIET_DEBUG_SWITCH
    133 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    134 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : load Elf-Header\n",
    135         x , y , p );
    136 #endif
    137 
    138     // get nsegments and Program-Header-Table offset from Elf-Header
    139     Elf32_Ehdr*  elf_header_ptr = (Elf32_Ehdr*)buf;
    140     unsigned int offset         = elf_header_ptr->e_phoff;
    141     unsigned int nsegments      = elf_header_ptr->e_phnum;
    142 
    143     // load Program-Header-Table from .elf file
    144     if ( _fat_lseek( fd, offset, SEEK_SET ) < 0 ) return 1;
    145     if ( _fat_read( fd, buf, 4096 ) < 0 ) return 1;
    146 
    147 #if GIET_DEBUG_SWITCH
    148 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    149 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : "
    150         "load Program-Header-Table\n", x , y , p );
    151 #endif
    152 
    153     // set Program-Header-Table pointer
    154     Elf32_Phdr*  elf_pht_ptr = (Elf32_Phdr*)buf;
    155    
    156     // scan segments to  load all loadable & writable segments
    157     unsigned int seg_id;
    158     for (seg_id = 0 ; seg_id < nsegments ; seg_id++)
    159     {
    160         if ( (elf_pht_ptr[seg_id].p_type == PT_LOAD) &&    // loadable
    161              (elf_pht_ptr[seg_id].p_flags & PF_W) )        // writable
    162         {
    163             // Get segment attributes
    164             unsigned int seg_vaddr  = elf_pht_ptr[seg_id].p_vaddr;
    165             unsigned int seg_offset = elf_pht_ptr[seg_id].p_offset;
    166             unsigned int seg_size   = elf_pht_ptr[seg_id].p_filesz;
    167 
    168             // load the segment
    169             if ( _fat_lseek( fd, seg_offset, SEEK_SET ) < 0 ) return 1;
    170             if ( _fat_read( fd, (void*)seg_vaddr, seg_size ) < 0 ) return 1;
    171 
    172 #if GIET_DEBUG_SWITCH
    173 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    174 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : load segment %x\n",
    175         x , y , p , seg_vaddr );
    176 #endif
    177 
    178         }
    179     }  // end loop on writable & loadable segments
    180 
    181     // close .elf file
    182     _fat_close( fd );
    183 
    184     return 0;
    185 }  // end load_writable_segments()
    186                              
    187 
    188 
    189 ///////////////////////////////////////////////
    190 static void _ctx_exec_task( unsigned int ltid )
    191 {
    192     // get pointers in mapping
    193     mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    194     mapping_task_t   * task    = _get_task_base(header);
    195     mapping_vseg_t   * vseg    = _get_vseg_base(header);
    196     mapping_vspace_t * vspace  = _get_vspace_base(header);
    197 
    198     // get scheduler address for processor running the calling task
    199     static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
    200 
    201     // get global task index, vspace index, and stack vseg index
    202     unsigned int task_id       = psched->context[ltid][CTX_GTID_ID];
    203     unsigned int vspace_id     = psched->context[ltid][CTX_VSID_ID];
    204     unsigned int vseg_id       = task[task_id].stack_vseg_id;
    205 
    206 #if GIET_DEBUG_SWITCH
    207 unsigned int gpid       = _get_procid();
    208 unsigned int cluster_xy = gpid >> P_WIDTH;
    209 unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    210 unsigned int x          = cluster_xy >> Y_WIDTH;
    211 unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    212 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    213 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _ctx_exec_task() : enters for %s\n",
    214         x , y , p , task[task_id].name );
    215 #endif
    216 
    217     // reload writable segments
    218     if ( _load_writable_segments( &vspace[vspace_id] ) )
    219     {
    220          _printf("[GIET ERROR] in _ctx_exec_task() for task %s\n",
    221                  task[task_id].name );
    222          return;
    223     }
    224 
    225     // find initial stack pointer
    226     unsigned int sp_value      = vseg[vseg_id].vbase + vseg[vseg_id].length;
    227 
    228     // reset task context: RA / SR / SP / EPC / NORUN
    229     psched->context[ltid][CTX_RA_ID]    = (unsigned int)&_ctx_eret;
    230     psched->context[ltid][CTX_SR_ID]    = GIET_SR_INIT_VALUE;
    231     psched->context[ltid][CTX_SP_ID]    = sp_value;
    232     psched->context[ltid][CTX_EPC_ID]   = psched->context[ltid][CTX_ENTRY_ID];
    233     psched->context[ltid][CTX_NORUN_ID] = 0;
    234 }
    23579
    23680
     
    302146        }
    303147
    304         // this task needs to be executed
    305         if ( psched->context[next_task_id][CTX_SIG_ID] & SIG_MASK_EXEC )
    306         {
    307             // acknowledge signal
    308             _atomic_and( &psched->context[next_task_id][CTX_SIG_ID], ~SIG_MASK_EXEC );
    309 
    310             _ctx_exec_task( next_task_id );
    311         }
    312 
    313148        // test if the task is runable
    314149        if ( psched->context[next_task_id][CTX_NORUN_ID] == 0 )
  • soft/giet_vm/giet_kernel/ctx_handler.h

    r696 r707  
    8989
    9090#define SIG_MASK_KILL         0x00000001   // Task will be killed at next tick
    91 #define SIG_MASK_EXEC         0x00000002   // Task will be executed at next tick
    9291
    9392/////////////////////////////////////////////////////////////////////////////////
  • 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
  • soft/giet_vm/giet_kernel/sys_handler.h

    r700 r707  
    240240int _sys_tasks_status();
    241241
     242int _sys_fat_read( unsigned int fd_id,
     243                   unsigned int buffer,
     244                   unsigned int count );
     245
    242246#endif
    243247
Note: See TracChangeset for help on using the changeset viewer.