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/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 )
Note: See TracChangeset for help on using the changeset viewer.