Changeset 407 for trunk/kernel


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

First implementation of fork/exec.

Location:
trunk/kernel
Files:
2 deleted
79 edited
4 copied
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/kernel/devices/dev_dma.c

    r406 r407  
    8888    thread_t * this = CURRENT_THREAD;
    8989
    90     dma_dmsg("\n[DMSG] %s : enters for thread %x / dst = %l /src = %l / size = %x\n",
     90    dma_dmsg("\n[DBG] %s : enters for thread %x / dst = %l /src = %l / size = %x\n",
    9191              __FUNCTION__ , this->trdid , dst_xp , src_xp , size );
    9292
     
    108108    // block client thread on THREAD_BLOCKED_IO and deschedule.
    109109    // it is re-activated by the ISR signaling IO operation completion.
    110     chdev_register_command( dev_xp , this );
     110    chdev_register_command( dev_xp );
    111111
    112     dma_dmsg("\n[DMSG] %s : completes for thread %x / error = %d\n",
     112    dma_dmsg("\n[DBG] %s : completes for thread %x / error = %d\n",
    113113             __FUNCTION__ ,  this->trdid , this->dma_cmd.error );
    114114
  • trunk/kernel/devices/dev_fbf.c

    r406 r407  
    143143    }
    144144
    145     fbf_dmsg("\n[DMSG] %s : thread %x in process %x / vaddr = %p / paddr = %l\n",
     145    fbf_dmsg("\n[DBG] %s : thread %x in process %x / vaddr = %p / paddr = %l\n",
    146146             __FUNCTION__ , this->trdid , this->process->pid , buffer , buf_paddr );
    147147
  • trunk/kernel/devices/dev_ioc.c

    r406 r407  
    5151
    5252    // set chdev name
    53     snprintf( ioc->name , 16 , "ioc_%d" , channel );
     53    snprintf( ioc->name , 16 , "ioc%d" , channel );
    5454
    5555    // call driver init function
     
    9090// It builds and registers the command in the calling thread descriptor.
    9191// Then, it registers the calling thead in chdev waiting queue.
    92 // Finally it blocks on the THREAD_BLOCKED_DEV condition and deschedule.
     92// Finally it blocks on the THREAD_BLOCKED_IO condition and deschedule.
    9393////////////////////////////////////i/////////////////////////////////////////////
    9494static error_t dev_ioc_access( uint32_t   cmd_type,
     
    9999    thread_t * this = CURRENT_THREAD;              // pointer on client thread
    100100
    101     ioc_dmsg("\n[DMSG] %s : thread %x in process %x"
     101    ioc_dmsg("\n[DBG] %s : thread %x in process %x"
    102102             " for lba = %x / buffer = %x / at cycle %d\n",
    103103             __FUNCTION__ , this->trdid , this->process->pid ,
     
    126126    // block client thread on THREAD_BLOCKED_IO and deschedule.
    127127    // it is re-activated by the ISR signaling IO operation completion.
    128     chdev_register_command( dev_xp , this );
    129 
    130     ioc_dmsg("\n[DMSG] in %s : thread %x in process %x"
     128    chdev_register_command( dev_xp );
     129
     130    ioc_dmsg("\n[DBG] in %s : thread %x in process %x"
    131131             " completes / error = %d / at cycle %d\n",
    132132             __FUNCTION__ , this->trdid , this->process->pid ,
     
    162162    thread_t * this = CURRENT_THREAD;
    163163
    164     ioc_dmsg("\n[DMSG] %s : core[%x,%d] enter for %d blocks / lba = %x / cycle %d\n",
     164    ioc_dmsg("\n[DBG] %s : core[%x,%d] enter for %d blocks / lba = %x / cycle %d\n",
    165165    __FUNCTION__ , local_cxy , this->core->lid , count , lba , hal_time_stamp() );
    166166
     
    199199    dev_pic_enable_irq( lid , ioc_xp );
    200200
    201     ioc_dmsg("\n[DMSG] %s : core[%x,%d] exit / error = %d / cycle %d\n",
     201    ioc_dmsg("\n[DBG] %s : core[%x,%d] exit / error = %d / cycle %d\n",
    202202    __FUNCTION__ , local_cxy , this->core->lid , this->ioc_cmd.error , hal_time_stamp() );
    203203
  • trunk/kernel/devices/dev_mmc.c

    r406 r407  
    9999    thread_t * this = CURRENT_THREAD;
    100100
    101     mmc_dmsg("\n[DMSG] %s enters for thread %x in process %x / buf_xp = %l\n",
     101    mmc_dmsg("\n[DBG] %s enters for thread %x in process %x / buf_xp = %l\n",
    102102                 __FUNCTION__ , this->trdid , this->process->pid , buf_xp );
    103103
     
    124124    error = dev_mmc_access( this );
    125125
    126     mmc_dmsg("\n[DMSG] %s completes for thread %x in process %x / error = %d\n",
     126    mmc_dmsg("\n[DBG] %s completes for thread %x in process %x / error = %d\n",
    127127             __FUNCTION__ , this->trdid , this->process->pid , error );
    128128
     
    139139    thread_t * this = CURRENT_THREAD;
    140140
    141     mmc_dmsg("\n[DMSG] %s enters for thread %x in process %x / buf_xp = %l\n",
     141    mmc_dmsg("\n[DBG] %s enters for thread %x in process %x / buf_xp = %l\n",
    142142                 __FUNCTION__ , this->trdid , this->process->pid , buf_xp );
    143143
     
    164164    error = dev_mmc_access( this );
    165165
    166     mmc_dmsg("\n[DMSG] %s completes for thread %x in process %x / error = %d\n",
     166    mmc_dmsg("\n[DBG] %s completes for thread %x in process %x / error = %d\n",
    167167                 __FUNCTION__ , this->trdid , this->process->pid , error );
    168168
  • trunk/kernel/devices/dev_nic.c

    r406 r407  
    5151
    5252    // set chdev name
    53     if( is_rx ) snprintf( nic->name , 16 , "nic_rx_%d" , channel );
    54     else        snprintf( nic->name , 16 , "nic_tx_%d" , channel );
     53    if( is_rx ) snprintf( nic->name , 16 , "nic%d_rx" , channel );
     54    else        snprintf( nic->name , 16 , "nic%d_tx" , channel );
    5555
    5656    // call driver init function
     
    9797    core_t * core = thread_ptr->core;
    9898
    99     nic_dmsg("\n[DMSG] %s enters for NIC-RX thread on core %d in cluster %x\n",
     99    nic_dmsg("\n[DBG] %s enters for NIC-RX thread on core %d in cluster %x\n",
    100100                 __FUNCTION__ , core->lid , local_cxy );
    101101
     
    129129        // block on THREAD_BLOCKED_IO condition and deschedule
    130130        thread_block( thread_ptr , THREAD_BLOCKED_IO );
    131         sched_yield( NULL );
     131        sched_yield();
    132132
    133133        // disable NIC-RX IRQ
     
    147147    pkd->length = thread_ptr->nic_cmd.length;
    148148
    149     nic_dmsg("\n[DMSG] %s exit for NIC-RX thread on core %d in cluster %x\n",
     149    nic_dmsg("\n[DBG] %s exit for NIC-RX thread on core %d in cluster %x\n",
    150150             __FUNCTION__ , core->lid , local_cxy );
    151151
     
    167167    core_t * core = thread_ptr->core;
    168168
    169     nic_dmsg("\n[DMSG] %s enters for NIC-RX thread on core %d in cluster %x\n",
     169    nic_dmsg("\n[DBG] %s enters for NIC-RX thread on core %d in cluster %x\n",
    170170                 __FUNCTION__ , core->lid , local_cxy );
    171171
     
    199199        // block on THREAD_BLOCKED I/O condition and deschedule
    200200        thread_block( thread_ptr , THREAD_BLOCKED_IO );
    201         sched_yield( NULL );
     201        sched_yield();
    202202
    203203        // disable NIC-TX IRQ
     
    215215    if( error ) return error;
    216216
    217     nic_dmsg("\n[DMSG] %s exit for NIC-TX thread on core %d in cluster %x\n",
     217    nic_dmsg("\n[DBG] %s exit for NIC-TX thread on core %d in cluster %x\n",
    218218             __FUNCTION__ , core->lid , local_cxy );
    219219
  • trunk/kernel/devices/dev_nic.h

    r14 r407  
    107107enum nic_impl_e
    108108{
    109     IMPL_NIC_SOC =   0,     
     109    IMPL_NIC_CBF =   0,     
    110110    IMPL_NIC_I86 =   1,
    111111}
  • trunk/kernel/devices/dev_pic.c

    r406 r407  
    3636
    3737extern chdev_directory_t  chdev_dir;         // allocated in kernel_init.c
     38extern iopic_input_t      iopic_input;       // allocated in kernel_init.c
    3839
    3940///////////////////////////////////
     
    8384                         xptr_t  src_chdev_xp )
    8485{
    85     irq_dmsg("\n[DMSG] %s : core = [%x,%d] / src_chdev_cxy = %x / src_chdev_ptr = %x\n",
    86     __FUNCTION__ , local_cxy , lid , GET_CXY(src_chdev_xp) , GET_PTR(src_chdev_xp) );
     86
     87irq_dmsg("\n[DBG] %s : core = [%x,%d] / src_chdev_cxy = %x / src_chdev_ptr = %x\n",
     88__FUNCTION__ , local_cxy , lid , GET_CXY(src_chdev_xp) , GET_PTR(src_chdev_xp) );
    8789
    8890    // get pointer on PIC chdev
     
    101103                          xptr_t  src_chdev_xp )
    102104{
    103     irq_dmsg("\n[DMSG] %s : core = [%x,%d] / src_chdev_cxy = %x / src_chdev_ptr = %x\n",
    104     __FUNCTION__ , local_cxy , lid , GET_CXY(src_chdev_xp) , GET_PTR(src_chdev_xp) );
     105
     106irq_dmsg("\n[DBG] %s : core = [%x,%d] / src_chdev_cxy = %x / src_chdev_ptr = %x\n",
     107__FUNCTION__ , local_cxy , lid , GET_CXY(src_chdev_xp) , GET_PTR(src_chdev_xp) );
    105108
    106109    // get pointer on PIC chdev
     
    118121void dev_pic_enable_timer( uint32_t period )
    119122{
    120     irq_dmsg("\n[DMSG] %s : core = [%x,%d] / period = %d\n",
    121     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , period );
     123
     124irq_dmsg("\n[DBG] %s : core = [%x,%d] / period = %d\n",
     125__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , period );
    122126
    123127    // get pointer on PIC chdev
     
    135139void dev_pic_enable_ipi()
    136140{
    137     irq_dmsg("\n[DMSG] %s : core = [%x,%d]\n",
    138     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
     141
     142irq_dmsg("\n[DBG] %s : core = [%x,%d] / cycle %d\n",
     143__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
    139144
    140145    // get pointer on PIC chdev
     
    153158                       lid_t  lid )
    154159{
    155     irq_dmsg("\n[DMSG] %s : enter / src_core = [%x,%d] / dst_core = [%x,%d] / cycle %d\n",
    156     __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, cxy, lid, hal_time_stamp() );
     160
     161irq_dmsg("\n[DBG] %s : src_core = [%x,%d] / dst_core = [%x,%d] / cycle %d\n",
     162__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, cxy, lid, hal_time_stamp() );
    157163
    158164    // get pointer on PIC chdev
     
    165171    // call relevant driver function
    166172    f( cxy , lid );
    167 
    168     irq_dmsg("\n[DMSG] %s : exit / src_core = [%x,%d] / dst_core = [%x,%d] / cycle %d\n",
    169     __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, cxy, lid, hal_time_stamp() );
    170 }
    171 
     173}
     174
     175//////////////////////
     176void dev_pic_ack_ipi()
     177{
     178
     179irq_dmsg("\n[DBG] %s : core = [%x,%d] / cycle %d\n",
     180__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, hal_time_stamp() );
     181
     182    // get pointer on PIC chdev
     183    chdev_t * pic_ptr = (chdev_t *)GET_PTR( chdev_dir.pic );
     184    cxy_t     pic_cxy = GET_CXY( chdev_dir.pic );
     185
     186    // get pointer on ack_ipi function
     187    ack_ipi_t * f = hal_remote_lpt( XPTR( pic_cxy , &pic_ptr->ext.pic.ack_ipi ) );
     188
     189    // call relevant driver function
     190    f();
     191}
     192
     193/////////////////////////////
     194void dev_pic_inputs_display()
     195{
     196    uint32_t k;
     197    uint32_t save_sr;
     198
     199    // get pointers on TXT0 chdev
     200    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
     201    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
     202    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     203
     204    // get extended pointer on remote TXT0 chdev lock
     205    xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
     206
     207    // get TXT0 lock in busy waiting mode
     208    remote_spinlock_lock_busy( lock_xp , &save_sr );
     209
     210    nolock_printk("\n***** iopic_inputs\n");
     211
     212    for( k = 0 ; k < CONFIG_MAX_IOC_CHANNELS ; k++ )
     213    {
     214        nolock_printk(" - IOC[%d]    hwi_id = %d\n", k , iopic_input.ioc[k] );
     215    }
     216
     217    for( k = 0 ; k < CONFIG_MAX_TXT_CHANNELS ; k++ )
     218    {
     219        nolock_printk(" - TXT_TX[%d] hwi_id = %d\n", k , iopic_input.txt_tx[k] );
     220        nolock_printk(" - TXT_RX[%d] hwi_id = %d\n", k , iopic_input.txt_rx[k] );
     221    }
     222
     223    for( k = 0 ; k < CONFIG_MAX_NIC_CHANNELS ; k++ )
     224    {
     225        nolock_printk(" - NIC_TX[%d] hwi_id = %d\n", k , iopic_input.nic_tx[k] );
     226        nolock_printk(" - NIC_RX[%d] hwi_id = %d\n", k , iopic_input.nic_rx[k] );
     227    }
     228
     229    // release TXT0 lock
     230    remote_spinlock_unlock_busy( lock_xp , save_sr );
     231}
     232
     233
  • trunk/kernel/devices/dev_pic.h

    r406 r407  
    8080/*****************************************************************************************
    8181 * This defines the specific extension for the PIC chdev descriptor.
    82  * It contains four function pointers on the four PIC command types,
    83  * that must be implemented by all drivers.
     82 * It contains the function pointers for all functions that mus be implemented
     83 * by all implementation specific drivers.
    8484 ****************************************************************************************/
    8585
     
    9090typedef void   (enable_ipi_t)   ( );   
    9191typedef void   (send_ipi_t)     ( cxy_t cxy , lid_t lid );
     92typedef void   (ack_ipi_t)      ( );   
    9293typedef void   (extend_init_t)  ( uint32_t * lapic_base );
    9394 
     
    9899    disable_irq_t   * disable_irq;   /*! pointer on the driver "disable_irq" function   */
    99100    enable_timer_t  * enable_timer;  /*! pointer on the driver "enable_timer" function  */
    100     enable_timer_t  * enable_ipi;    /*! pointer on the driver "enable_ipi" function    */
     101    enable_ipi_t    * enable_ipi;    /*! pointer on the driver "enable_ipi" function    */
    101102    send_ipi_t      * send_ipi;      /*! pointer on the driver "send_ipi" function      */
     103    ack_ipi_t       * ack_ipi;       /*! pointer on the driver "ack_ipi" function       */
    102104    extend_init_t   * extend_init;   /*! pointer on the driver "init_extend" function   */
    103105}
     
    109111 * It describes the hardware wiring of IRQs between external peripherals and the IOPIC,
    110112 * as each entry contains the input IRQ index in IOPIC.
    111  * For a multi-channels peripheral, there is one chdev and one IRQ per channel.
     113 * For a multi-channels/multi_IRQ peripheral, there is one chdev per IRQ.
    112114 * This structure is replicated in each cluster. It is allocated as a global variable
    113115 * in the kernel_init.c file.
     
    116118typedef struct iopic_input_s
    117119{
    118     uint32_t   txt[CONFIG_MAX_TXT_CHANNELS];
    119120    uint32_t   ioc[CONFIG_MAX_IOC_CHANNELS];
     121    uint32_t   txt_rx[CONFIG_MAX_TXT_CHANNELS];
     122    uint32_t   txt_tx[CONFIG_MAX_TXT_CHANNELS];
    120123    uint32_t   nic_rx[CONFIG_MAX_NIC_CHANNELS];
    121124    uint32_t   nic_tx[CONFIG_MAX_NIC_CHANNELS];
     
    180183 * This is a static binding, defined during kernel init: IRQ can be enabled/disabled,
    181184 * but the binding cannot be released. It can be used for both internal & external IRQs.
     185 * The configuration is actually done by the - implementation specific - driver,
     186 * and this function just call the relevant driver.
    182187 * WARNING : the IRQ must be explicitely enabled by the dev_pic_enable_irq() function.
    183188 *****************************************************************************************
     
    234239                       lid_t  lid );
    235240
     241/*****************************************************************************************
     242 * This function acknowledges the IPI identified by the calling core local index,
     243 * in the local LAPIC component.
     244 ****************************************************************************************/
     245void dev_pic_ack_ipi();
     246
     247/*****************************************************************************************
     248 * This debug function displays the content of the iopic_input structure,
     249 * that register the input IRQS for the external IOPIC controller.
     250 ****************************************************************************************/
     251void dev_pic_inputs_display();
    236252
    237253#endif  /* _DEV_PIC_H_ */
  • trunk/kernel/devices/dev_txt.c

    r406 r407  
    2727#include <hal_drivers.h>
    2828#include <thread.h>
     29#include <chdev.h>
    2930#include <rpc.h>
    3031#include <printk.h>
     
    3637
    3738extern chdev_directory_t  chdev_dir;         // allocated in kernel_init.c
     39
     40#if CONFIG_READ_DEBUG
     41extern uint32_t enter_txt_read;
     42extern uint32_t exit_txt_read;
     43#endif
    3844
    3945//////////////////////////////////
     
    4753    uint32_t  channel = txt->channel;
    4854    uint32_t  impl    = txt->impl;
     55    bool_t    is_rx   = txt->is_rx;
    4956
    5057    assert( (pic_xp != XPTR_NULL) || (channel == 0) , __FUNCTION__ ,
     
    5259
    5360    // set chdev name
    54     snprintf( txt->name , 16 , "txt_%d" , channel );
     61    if( is_rx ) snprintf( txt->name , 16 , "txt%d_rx" , channel );
     62    else        snprintf( txt->name , 16 , "txt%d_tx" , channel );
    5563
    5664    // call driver init function
     
    6169    if( channel != 0 && impl != IMPL_TXT_RS2 )
    6270    {
    63         // select a core to execute the TXT server thread
     71        // select a core to execute the server thread
    6472        lid_t lid = cluster_select_local_core();
    6573
    66         // bind TXT IRQ to the selected core
     74        // bind IRQ to the selected core
    6775        dev_pic_bind_irq( lid , txt );
    6876
    69         // enable TXT IRQ
     77        // enable IRQ
    7078        dev_pic_enable_irq( lid , XPTR( local_cxy , txt ) );
    7179
     
    99107                               uint32_t   count )
    100108{
     109    xptr_t     dev_xp;
    101110    thread_t * this = CURRENT_THREAD;
    102111
    103     txt_dmsg("\n[DMSG] in %s : thread %x in process %x enters\n",
    104                  __FUNCTION__ , this->trdid , this->process->pid );
     112txt_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) enters / cycle %d\n",
     113__FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type), hal_time_stamp() );
    105114
    106115    // check channel argument
     
    108117
    109118    // get extended pointer on remote TXT chdev descriptor
    110     xptr_t  dev_xp = chdev_dir.txt[channel];
     119    if( type == TXT_WRITE )  dev_xp = chdev_dir.txt_tx[channel];
     120    else                     dev_xp = chdev_dir.txt_rx[channel];
    111121
    112122    assert( (dev_xp != XPTR_NULL) , __FUNCTION__ , "undefined TXT chdev descriptor" );
     
    121131    // block client thread on THREAD_BLOCKED_IO and deschedule.
    122132    // it is re-activated by the ISR signaling IO operation completion.
    123     chdev_register_command( dev_xp , this );
     133    chdev_register_command( dev_xp );
    124134
    125     txt_dmsg("\n[DMSG] in %s : thread %x in process %x completes / error = %d\n",
    126              __FUNCTION__ , this->trdid , this->process->pid , this->txt_cmd.error );
     135txt_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) exit / cycle %d\n",
     136__FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type), hal_time_stamp() );
    127137
    128138    // return I/O operation status from calling thread descriptor
     
    135145                       uint32_t   count )
    136146{
    137     return dev_txt_access( TXT_WRITE , channel , buffer , count );
     147    error_t error = dev_txt_access( TXT_WRITE , channel , buffer , count );
     148    return error;
    138149}
    139150
     
    142153                      char     * buffer )
    143154{
    144     return dev_txt_access( TXT_READ , channel , buffer , 1 );
     155
     156#if CONFIG_READ_DEBUG
     157enter_txt_read = hal_time_stamp();
     158#endif
     159
     160    error_t error = dev_txt_access( TXT_READ , channel , buffer , 1 );
     161
     162#if CONFIG_READ_DEBUG
     163exit_txt_read = hal_time_stamp();
     164#endif
     165
     166    return error;
     167
    145168}
    146169
    147 ///////////////////////////////////////////////
    148 error_t dev_txt_sync_write( uint32_t   channel,
    149                             char     * buffer,
     170//////////////////////////////////////////////
     171error_t dev_txt_sync_write( char     * buffer,
    150172                            uint32_t   count )
    151173{
    152     // get pointer on calling thread
    153     thread_t * this = CURRENT_THREAD;
     174    // get extended pointer on TXT[0] chdev
     175    xptr_t  dev_xp = chdev_dir.txt_tx[0];
    154176
    155     // get extended pointer on TXT[0] chdev
    156     xptr_t  dev_xp = chdev_dir.txt[channel];
     177    assert( (dev_xp != XPTR_NULL) , __FUNCTION__ ,
     178    "undefined TXT0 chdev descriptor" );
    157179
    158     assert( (dev_xp != XPTR_NULL) , __FUNCTION__ , "undefined TXT0 chdev descriptor" );
    159 
    160     // register command in calling thread descriptor
    161     this->txt_cmd.dev_xp  = dev_xp;
    162     this->txt_cmd.type    = TXT_SYNC_WRITE;
    163     this->txt_cmd.buf_xp  = XPTR( local_cxy , buffer );
    164     this->txt_cmd.count   = count;
     180    // get TXTO chdev cluster and local pointer
     181    cxy_t    dev_cxy  = GET_CXY( dev_xp );
     182    chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    165183
    166184    // get driver command function
    167     cxy_t       dev_cxy = GET_CXY( dev_xp );
    168     chdev_t   * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    169     dev_cmd_t * cmd = (dev_cmd_t *)hal_remote_lpt( XPTR( dev_cxy , &dev_ptr->cmd ) );
     185    dev_aux_t * aux = (dev_aux_t *)hal_remote_lpt( XPTR( dev_cxy , &dev_ptr->aux ) );
     186
     187    // build arguments structure
     188    txt_aux_t  args;
     189    args.dev_xp = dev_xp;
     190    args.buffer = buffer;
     191    args.count  = count;
    170192
    171193    // call driver function
    172     cmd( XPTR( local_cxy , this ) );
     194    aux( &args );
    173195
    174     // return I/O operation status from calling thread descriptor
    175     return this->txt_cmd.error;
     196    return 0;
    176197}
    177198
  • trunk/kernel/devices/dev_txt.h

    r254 r407  
    3636 *
    3737 * This multi-channels generic TXT device provides access to a text terminal.
    38  * It supports three operation types :
     38 *
     39 * It supports two operations that must be implemented by the driver cmd() function:
    3940 * - TXT_READ : read a single character from the text terminal identified by its channel
    4041 *   index, using a descheduling strategy for the calling thread.
    4142 * - TXT_WRITE : write a character string to the text terminal identified by its channel
    4243 *   index, using a descheduling strategy for the calling thread.
    43  * - TXT_SYNC_WRITE : write a character string to the terminal identified by its channel
    44  *   index, using a busy waiting strategy for the calling thread.
     44 *
     45 * It supports one operation, that must be implemented by the driver aux() function 
     46 * - TXT_SYNC_WRITE write a character string to the TXT0 kernel terminal, using a busy
     47 *   waiting strategy for the calling thread.
    4548 *****************************************************************************************/
    4649
     
    5861
    5962/******************************************************************************************
    60  * This defines the (implementation independent) command passed to the driver.
     63 * This defines the arguments passed to the driver CMD function.
    6164 *****************************************************************************************/
    6265
     
    6568    TXT_READ       = 0,
    6669    TXT_WRITE      = 1,
    67     TXT_SYNC_WRITE = 2,
    6870};
    6971
     
    7779}
    7880txt_command_t;
     81
     82/******************************************************************************************
     83 * This defines the arguments passed to the driver AUX function.
     84 * This function implement the TXT_SYNC_WRITE operation.
     85 *****************************************************************************************/
     86
     87typedef struct txt_aux_s
     88{
     89    xptr_t      dev_xp;    /*! extended pointer on the TXT0 device descriptor            */
     90    char      * buffer;    /*! local pointer on characters array                         */
     91    uint32_t    count;     /*! number of characters in buffer                            */
     92}
     93txt_aux_t;
    7994
    8095/******************************************************************************************
     
    122137
    123138/***************************************************************************************
    124  * This low-level blocking function is used by the kernel to display one string on a
    125  * given TXT channel without descheduling the calling thread, without registering it
    126  * in the TXT device waiting queue, and without using the TXT irq.
     139 * This blocking function is used by the kernel to display a string on the TXT0
     140 * terminal, without descheduling the calling thread, without registering it
     141 * in the TXT0 device waiting queue, without using the TXT0 irq, and without
     142 * interfering with another possible TXT access to another terminal.
     143 * As it is used for debug, the command arguments <buffer> and <count> are registerd
     144 * in a specific "dbg_cmd" field of the calling thread.
     145 * other TXT accesses.
    127146 ****************************************************************************************
    128  * @ channel   : TXT channel index.
    129147 * @ buffer    : local pointer on source buffer containing the string.
    130148 * @ count     : number of characters.
    131149 * @ returns 0 if success / returns EINVAL if error.
    132150 ***************************************************************************************/
    133 error_t dev_txt_sync_write( uint32_t   channel,
    134                             char     * buffer,
     151error_t dev_txt_sync_write( char     * buffer,
    135152                            uint32_t   count );
    136153
  • trunk/kernel/fs/devfs.c

    r406 r407  
    2525#include <hal_types.h>
    2626#include <hal_special.h>
     27#include <hal_uspace.h>
    2728#include <printk.h>
    2829#include <chdev.h>
     30#include <dev_txt.h>
    2931#include <cluster.h>
    3032#include <vfs.h>
     
    3941extern chdev_directory_t    chdev_dir;      // allocated in kernel_init.c
    4042
     43#if CONFIG_READ_DEBUG
     44extern uint32_t  enter_devfs_move;
     45extern uint32_t  exit_devfs_move;
     46#endif
     47
    4148///////////////////////////////
    4249devfs_ctx_t * devfs_ctx_alloc()
     
    7986    error_t  error;
    8087
    81     devfs_dmsg("\n[DMSG] %s : enter in cluster %x\n",
     88    devfs_dmsg("\n[DBG] %s : enter in cluster %x\n",
    8289               __FUNCTION__ , local_cxy );
    8390
     
    93100    assert( (error == 0) , __FUNCTION__ , "cannot create <dev>\n" );
    94101
    95     devfs_dmsg("\n[DMSG] %s : <dev> created in cluster %x\n",
     102    devfs_dmsg("\n[DBG] %s : <dev> created in cluster %x\n",
    96103               __FUNCTION__ , local_cxy );
    97104
     
    107114    assert( (error == 0) , __FUNCTION__ , "cannot create <external>\n" );
    108115
    109     devfs_dmsg("\n[DMSG] %s : <external> created in cluster %x\n",
     116    devfs_dmsg("\n[DBG] %s : <external> created in cluster %x\n",
    110117               __FUNCTION__ , local_cxy );
    111118}
     
    119126    xptr_t        chdev_xp;
    120127    cxy_t         chdev_cxy;
     128    chdev_t     * chdev_ptr;
    121129    xptr_t        inode_xp;
    122130    uint32_t      channel;
     
    132140                             devfs_internal_inode_xp );
    133141
     142devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n",
     143__FUNCTION__ , node_name , local_cxy );
     144
    134145    // create MMC chdev inode
    135     chdev_xp = chdev_dir.mmc[local_cxy];
     146    chdev_xp  = chdev_dir.mmc[local_cxy];
    136147    if( chdev_xp != XPTR_NULL)
    137148    {
     149        chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
    138150        vfs_add_child_in_parent( local_cxy,
    139151                                 INODE_TYPE_DEV,
    140152                                 FS_TYPE_DEVFS,
    141153                                 *devfs_internal_inode_xp,
    142                                  "mmc",
     154                                 chdev_ptr->name,
    143155                                 GET_PTR( chdev_xp ),
    144156                                 &inode_xp );
     157
     158devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n",
     159__FUNCTION__ , chdev_ptr->name , local_cxy );
     160
    145161    }
    146162
     
    151167        if( chdev_xp != XPTR_NULL)
    152168        {
    153             snprintf( node_name , 16 , "dma_%d" , channel );
     169            chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
    154170            vfs_add_child_in_parent( local_cxy,
    155171                                     INODE_TYPE_DEV,
    156172                                     FS_TYPE_DEVFS,
    157173                                     *devfs_internal_inode_xp,
    158                                      node_name,
     174                                     chdev_ptr->name,
    159175                                     GET_PTR( chdev_xp ),
    160176                                     &inode_xp );
     177
     178devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n",
     179__FUNCTION__ , chdev_ptr->name , local_cxy );
     180
    161181        }
    162182    }
     
    167187    {
    168188        chdev_cxy = GET_CXY( chdev_xp );
     189        chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
    169190        if( chdev_cxy == local_cxy )
    170191        {
     
    173194                                     FS_TYPE_DEVFS,
    174195                                     devfs_external_inode_xp,
    175                                      "iob",
     196                                     chdev_ptr->name,
    176197                                     GET_PTR( chdev_xp ),
    177198                                     &inode_xp );
     199
     200devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n",
     201__FUNCTION__ , chdev_ptr->name , local_cxy );
     202
    178203        }
    179204    }
     
    184209    {
    185210        chdev_cxy = GET_CXY( chdev_xp );
     211        chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
    186212        if( chdev_cxy == local_cxy )
    187213        {
     
    190216                                     FS_TYPE_DEVFS,
    191217                                     devfs_external_inode_xp,
    192                                      "pic",
     218                                     chdev_ptr->name,
    193219                                     GET_PTR( chdev_xp ),
    194220                                     &inode_xp );
    195         }
    196     }
    197 
    198     // create a TXT inode in each cluster containing a TXT chdev
     221
     222devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n",
     223__FUNCTION__ , chdev_ptr->name , local_cxy );
     224
     225        }
     226    }
     227
     228    // create a TXT_RX inode in each cluster containing a TXT_RX chdev
    199229    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
    200230    {
    201         chdev_xp = chdev_dir.txt[channel];
    202         if( chdev_xp != XPTR_NULL )
    203         {
    204             chdev_cxy = GET_CXY( chdev_xp );
    205             if( chdev_cxy == local_cxy )
    206             {
    207                 snprintf( node_name , 16 , "txt_%d" , channel );
    208                 vfs_add_child_in_parent( local_cxy,
    209                                          INODE_TYPE_DEV,
    210                                          FS_TYPE_DEVFS,
    211                                          devfs_external_inode_xp,
    212                                          node_name,
    213                                          GET_PTR( chdev_xp ),
    214                                          &inode_xp );
     231        chdev_xp = chdev_dir.txt_rx[channel];
     232        if( chdev_xp != XPTR_NULL )
     233        {
     234            chdev_cxy = GET_CXY( chdev_xp );
     235            chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
     236            if( chdev_cxy == local_cxy )
     237            {
     238                vfs_add_child_in_parent( local_cxy,
     239                                         INODE_TYPE_DEV,
     240                                         FS_TYPE_DEVFS,
     241                                         devfs_external_inode_xp,
     242                                         chdev_ptr->name,
     243                                         GET_PTR( chdev_xp ),
     244                                         &inode_xp );
     245
     246devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n",
     247__FUNCTION__ , chdev_ptr->name , local_cxy );
     248
     249            }
     250        }
     251    }
     252
     253    // create a TXT_TX inode in each cluster containing a TXT_TX chdev
     254    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
     255    {
     256        chdev_xp = chdev_dir.txt_tx[channel];
     257        if( chdev_xp != XPTR_NULL )
     258        {
     259            chdev_cxy = GET_CXY( chdev_xp );
     260            chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
     261            if( chdev_cxy == local_cxy )
     262            {
     263                vfs_add_child_in_parent( local_cxy,
     264                                         INODE_TYPE_DEV,
     265                                         FS_TYPE_DEVFS,
     266                                         devfs_external_inode_xp,
     267                                         chdev_ptr->name,
     268                                         GET_PTR( chdev_xp ),
     269                                         &inode_xp );
     270
     271devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n",
     272__FUNCTION__ , chdev_ptr->name , local_cxy );
     273
    215274            }
    216275        }
     
    224283        {
    225284            chdev_cxy = GET_CXY( chdev_xp );
    226             if( chdev_cxy == local_cxy )
    227             {
    228                 snprintf( node_name , 16 , "ioc_%d" , channel );
    229                 vfs_add_child_in_parent( local_cxy,
    230                                          INODE_TYPE_DEV,
    231                                          FS_TYPE_DEVFS,
    232                                          devfs_external_inode_xp,
    233                                          node_name,
    234                                          GET_PTR( chdev_xp ),
    235                                          &inode_xp );
     285            chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
     286            if( chdev_cxy == local_cxy )
     287            {
     288                vfs_add_child_in_parent( local_cxy,
     289                                         INODE_TYPE_DEV,
     290                                         FS_TYPE_DEVFS,
     291                                         devfs_external_inode_xp,
     292                                         chdev_ptr->name,
     293                                         GET_PTR( chdev_xp ),
     294                                         &inode_xp );
     295
     296devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n",
     297__FUNCTION__ , chdev_ptr->name , local_cxy );
     298
    236299            }
    237300        }
     
    245308        {
    246309            chdev_cxy = GET_CXY( chdev_xp );
    247             if( chdev_cxy == local_cxy )
    248             {
    249                 snprintf( node_name , 16 , "fbf_%d" , channel );
    250                 vfs_add_child_in_parent( local_cxy,
    251                                          INODE_TYPE_DEV,
    252                                          FS_TYPE_DEVFS,
    253                                          devfs_external_inode_xp,
    254                                          node_name,
    255                                          GET_PTR( chdev_xp ),
    256                                          &inode_xp );
     310            chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
     311            if( chdev_cxy == local_cxy )
     312            {
     313                vfs_add_child_in_parent( local_cxy,
     314                                         INODE_TYPE_DEV,
     315                                         FS_TYPE_DEVFS,
     316                                         devfs_external_inode_xp,
     317                                         chdev_ptr->name,
     318                                         GET_PTR( chdev_xp ),
     319                                         &inode_xp );
     320
     321devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n",
     322__FUNCTION__ , chdev_ptr->name , local_cxy );
     323
    257324            }
    258325        }
     
    266333        {
    267334            chdev_cxy = GET_CXY( chdev_xp );
    268             if( chdev_cxy == local_cxy )
    269             {
    270                 snprintf( node_name , 16 , "nic_rx_%d" , channel );
    271                 vfs_add_child_in_parent( local_cxy,
    272                                          INODE_TYPE_DEV,
    273                                          FS_TYPE_DEVFS,
    274                                          devfs_external_inode_xp,
    275                                          node_name,
    276                                          GET_PTR( chdev_xp ),
    277                                          &inode_xp );
     335            chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
     336            if( chdev_cxy == local_cxy )
     337            {
     338                vfs_add_child_in_parent( local_cxy,
     339                                         INODE_TYPE_DEV,
     340                                         FS_TYPE_DEVFS,
     341                                         devfs_external_inode_xp,
     342                                         chdev_ptr->name,
     343                                         GET_PTR( chdev_xp ),
     344                                         &inode_xp );
     345
     346devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n",
     347__FUNCTION__ , chdev_ptr->name , local_cxy );
     348
    278349            }
    279350        }
     
    287358        {
    288359            chdev_cxy = GET_CXY( chdev_xp );
    289             if( chdev_cxy == local_cxy )
    290             {
    291                 snprintf( node_name , 16 , "nic_tx_%d" , channel );
    292                 vfs_add_child_in_parent( local_cxy,
    293                                          INODE_TYPE_DEV,
    294                                          FS_TYPE_DEVFS,
    295                                          devfs_external_inode_xp,
    296                                          node_name,
    297                                          GET_PTR( chdev_xp ),
    298                                          &inode_xp );
     360            chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
     361            if( chdev_cxy == local_cxy )
     362            {
     363                vfs_add_child_in_parent( local_cxy,
     364                                         INODE_TYPE_DEV,
     365                                         FS_TYPE_DEVFS,
     366                                         devfs_external_inode_xp,
     367                                         chdev_ptr->name,
     368                                         GET_PTR( chdev_xp ),
     369                                         &inode_xp );
     370
     371devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n",
     372__FUNCTION__ , chdev_ptr->name , local_cxy );
     373
    299374            }
    300375        }
     
    302377}  // end devfs_local_init()
    303378
     379//////////////////////////////////////////
     380int devfs_user_move( bool_t     to_buffer,
     381                     xptr_t     file_xp,
     382                     void     * u_buf,
     383                     uint32_t   size )
     384{
     385    assert( ( file_xp != XPTR_NULL ) , __FUNCTION__ , "file_xp == XPTR_NULL" );
     386
     387    assert( ( size < CONFIG_TXT_KBUF_SIZE ) , __FUNCTION__ , "string size too large" );
     388
     389    cxy_t              file_cxy;     // remote file descriptor cluster
     390    vfs_file_t       * file_ptr;     // remote file descriptor local pointer
     391    vfs_inode_type_t   inode_type;   // associated inode type
     392    vfs_inode_t      * inode_ptr;    // associated inode local pointer
     393    chdev_t          * chdev_ptr;    // associated chdev type
     394    uint32_t           func;         // chdev functionnal type
     395    uint32_t           channel;      // chdev channel index
     396    error_t            error;
     397
     398    char               k_buf[CONFIG_TXT_KBUF_SIZE];  // local kernel buffer
     399
     400devfs_dmsg("\n[DBG] %s enter / cycle %d\n",
     401__FUNCTION__ , hal_time_stamp() );
     402
     403#if CONFIG_READ_DEBUG
     404enter_devfs_move = hal_time_stamp();
     405#endif
     406
     407    // get cluster and local pointer on remote file descriptor
     408    // associated inode and chdev are stored in same cluster as the file desc.
     409    file_cxy  = GET_CXY( file_xp );
     410    file_ptr  = (vfs_file_t *)GET_PTR( file_xp );
     411
     412    // get inode type from remote file descriptor
     413    inode_type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type ) );
     414    inode_ptr  = (vfs_inode_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) );
     415
     416    assert( (inode_type == INODE_TYPE_DEV) , __FUNCTION__ ,
     417    "inode type is not INODE_TYPE_DEV" );
     418
     419    // get chdev local pointer from remote inode extension
     420    chdev_ptr = (chdev_t *)hal_remote_lpt( XPTR( file_cxy , &inode_ptr->extend ) );
     421 
     422    // get chdev functionnal type and channel
     423    func    = hal_remote_lw( XPTR( file_cxy , &chdev_ptr->func ) );
     424    channel = hal_remote_lw( XPTR( file_cxy , &chdev_ptr->channel ) );
     425
     426    // action depends on "func" and "to_buffer"
     427    if( func == DEV_FUNC_TXT )
     428    {
     429        if( to_buffer )     // TXT read
     430        {
     431            uint32_t i;
     432            for( i = 0 ; i < size ; i++ )
     433            {
     434                error = dev_txt_read( channel , &k_buf[i] );
     435
     436                if( error )
     437                {
     438
     439devfs_dmsg("\n[DBG] %s exit error / cycle %d\n",
     440__FUNCTION__ , hal_time_stamp() );
     441
     442                    return -1;
     443                }
     444                else
     445                {
     446                    hal_strcpy_to_uspace( u_buf , k_buf , size );
     447                }
     448             }
     449
     450#if CONFIG_READ_DEBUG
     451exit_devfs_move = hal_time_stamp();
     452#endif
     453
     454devfs_dmsg("\n[DBG] %s exit success / size = %d / cycle %d\n",
     455__FUNCTION__ , size , hal_time_stamp() );
     456
     457            return size;
     458        }
     459        else                // TXT write 
     460        {
     461            hal_strcpy_from_uspace( k_buf , u_buf , size );
     462
     463            error = dev_txt_write( channel , k_buf , size );
     464            if( error )
     465            {
     466
     467devfs_dmsg("\n[DBG] %s exit error / cycle %d\n",
     468__FUNCTION__ , hal_time_stamp() );
     469
     470                return -1;
     471            }
     472            else
     473            {
     474
     475devfs_dmsg("\n[DBG] %s exit success / size = %d / cycle %d\n",
     476__FUNCTION__ , size , hal_time_stamp() );
     477
     478                return size;
     479            }
     480        }
     481    }
     482    else
     483    {
     484        panic("device type %s does not support direct user access", chdev_func_str(func) );
     485
     486        return -1;
     487    }
     488}  // end devfs_user_move()
     489
     490
  • trunk/kernel/fs/devfs.h

    r238 r407  
    4141//
    4242// The DEVFS extensions to the generic VFS are the following:
    43 // 1) The vfs_ctx_t "extend" field is a void* pointing on the devfs_ctx_t structure.
     43// 1) The vfs_ctx_t "extend" void* field is pointing on the devfs_ctx_t structure.
    4444//    This structure contains two extended pointers on the DEVFS "dev" directory inode,
    4545//    and on the "external" directory inode.
    46 // 2) The vfs_inode_t "extend" field is a void*, pointing on the associated
    47 //    chdev descriptor.
     46// 2) The vfs_inode_t "extend" void* field is pointing on the chdev descriptor.
    4847//////////////////////////////////////////////////////////////////////////////////////////
    4948
     
    119118                       xptr_t * devfs_internal_inode_xp );
    120119                       
     120/******************************************************************************************
     121 * This function moves <size> bytes between a device, and a - possibly distributed -
     122 * user space <buffer>. It uses the <file_xp> and <to_buffer> arguments, to call the
     123 * relevant device access function.
     124 * It is called by the sys_read() and sys_write() functions.
     125 * The <size> argument cannot be larger than the CONFIG_TXT_KBUF_SIZE configuration
     126 * parameter, as this function makes a copy between the user space buffer, and a local
     127 * kernel buffer allocated in the kernel stack.
     128 ******************************************************************************************
     129 * @ to_buffer : device -> buffer if true / buffer -> device if false.
     130 * @ file_xp   : extended pointer on the remote file descriptor.
     131 * @ u_buf     : user space buffer (virtual address).
     132 * @ size      : requested number of bytes from offset.
     133 * @ returns number of bytes actually moved if success / -1 if error.
     134 *****************************************************************************************/
     135int devfs_user_move( bool_t   to_buffer,
     136                     xptr_t   file_xp,
     137                     void   * u_buf,
     138                     uint32_t size );
     139
     140
    121141#endif  /* _DEVFS_H_ */
  • trunk/kernel/fs/fatfs.c

    r406 r407  
    262262    "no FAT access required for first page\n");
    263263
    264     fatfs_dmsg("\n[DMSG] %s : enter / first_cluster_id = %d / searched_page_index = %d\n",
    265     __FUNCTION__ , first_cluster_id , searched_page_index );
     264fatfs_dmsg("\n[DBG] %s : core[%x,%d] enters / first_cluster_id = %d / searched_index = %d\n",
     265__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, first_cluster_id, searched_page_index );
    266266
    267267    // get number of FAT slots per page
     
    289289        next_cluster_id = current_page_buffer[current_page_offset];
    290290
    291         fatfs_dmsg("\n[DMSG] %s : traverse FAT / current_page_index = %d\n"
    292                    "       current_page_offset = %d / next_cluster_id = %d\n",
    293         __FUNCTION__ , current_page_index , current_page_offset , next_cluster_id );
     291fatfs_dmsg("\n[DBG] %s : core[%x,%d] traverse FAT / current_page_index = %d\n"
     292"current_page_offset = %d / next_cluster_id = %d\n",
     293__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, current_page_index,
     294current_page_offset , next_cluster_id );
    294295
    295296        // update loop variables
     
    301302    if( next_cluster_id == 0xFFFFFFFF ) return EIO;
    302303   
    303     fatfs_dmsg("\n[DMSG] %s : exit / cluster_id = %d\n", __FUNCTION__ , next_cluster_id );
     304fatfs_dmsg("\n[DBG] %s : core[%x;%d] exit / cluster_id = %d\n",
     305__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, next_cluster_id );
    304306
    305307    *searched_cluster_id = next_cluster_id;
     
    333335    uint8_t     * buffer;
    334336
    335     fatfs_dmsg("\n[DMSG] %s : enter for fatfs_ctx = %x\n",
     337    fatfs_dmsg("\n[DBG] %s : enter for fatfs_ctx = %x\n",
    336338               __FUNCTION__ , fatfs_ctx );
    337339
     
    347349                   "cannot allocate memory for 512 bytes buffer\n" );
    348350     
    349     fatfs_dmsg("\n[DMSG] %s : allocated 512 bytes buffer\n", __FUNCTION__ );
     351    fatfs_dmsg("\n[DBG] %s : allocated 512 bytes buffer\n", __FUNCTION__ );
    350352
    351353    // load the boot record from device
     
    353355    error = dev_ioc_sync_read( buffer , 0 , 1 );
    354356
    355     fatfs_dmsg("\n[DMSG] %s : buffer loaded\n", __FUNCTION__ );
     357fatfs_dmsg("\n[DBG] %s : buffer loaded\n", __FUNCTION__ );
    356358
    357359    assert( (error == 0) , __FUNCTION__ , "cannot access boot record\n" );
     
    415417    kmem_free( &req );
    416418
    417     fatfs_dmsg("\n[DMSG] %s : boot record read & released\n",
     419    fatfs_dmsg("\n[DBG] %s : boot record read & released\n",
    418420               __FUNCTION__ );
    419421
     
    437439    fatfs_ctx->fat_mapper_xp         = XPTR( local_cxy , fat_mapper );
    438440
    439     fatfs_dmsg("\n[DMSG] %s : exit for fatfs_ctx = %x\n",
    440                __FUNCTION__ , fatfs_ctx );
     441fatfs_dmsg("\n[DBG] %s : exit for fatfs_ctx = %x\n", __FUNCTION__ , fatfs_ctx );
    441442
    442443}  // end fatfs_ctx_init()
     
    471472    inode = mapper->inode;
    472473
    473     fatfs_dmsg("\n[DMSG] %s : core[%x,%d] enter for page %d / inode %x / mapper %x\n",
    474     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , index , inode , mapper );
     474fatfs_dmsg("\n[DBG] %s : core[%x,%d] enter for page %d / inode %x / mapper %x\n",
     475__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , index , inode , mapper );
    475476
    476477    // get page base address
     
    488489        lba = fatfs_ctx->fat_begin_lba + (count * index);
    489490 
    490         fatfs_dmsg("\n[DMSG] %s : core[%x,%d] access FAT on device / lba = %d\n",
    491         __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , lba );
     491fatfs_dmsg("\n[DBG] %s : core[%x,%d] access FAT on device / lba = %d\n",
     492__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , lba );
    492493
    493494        // access device
     
    511512        else                        // FAT mapper access required
    512513        {
    513             fatfs_dmsg("\n[DMSG] %s : core[%x,%d] must access FAT\n",
    514             __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
    515 
    516514            // get cluster and local pointer on FAT mapper
    517515            xptr_t     fat_mapper_xp  = fatfs_ctx->fat_mapper_xp;
     
    522520            if( fat_mapper_cxy == local_cxy )    // FAT mapper is local
    523521            {
     522
     523fatfs_dmsg("\n[DBG] %s : core[%x,%d] access local FAT mapper\n"
     524"fat_mapper_cxy = %x / fat_mapper_ptr = %x / first_cluster_id = %d / index = %d\n",
     525__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid ,
     526fat_mapper_cxy , fat_mapper_ptr , first_cluster_id , index );
     527
    524528                error = fatfs_get_cluster( fat_mapper_ptr,
    525529                                           first_cluster_id,
     
    529533            else                                 // FAT mapper is remote
    530534            {
     535
     536fatfs_dmsg("\n[DBG] %s : core[%x,%d] access remote FAT mapper\n"
     537"fat_mapper_cxy = %x / fat_mapper_ptr = %x / first_cluster_id = %d / index = %d\n",
     538__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid ,
     539fat_mapper_cxy , fat_mapper_ptr , first_cluster_id , index );
     540
    531541                rpc_fatfs_get_cluster_client( fat_mapper_cxy,
    532542                                              fat_mapper_ptr,
     
    540550        }
    541551
    542         fatfs_dmsg("\n[DMSG] %s : core[%x,%d] access device for inode %x / cluster_id %d\n",
    543         __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , inode , searched_cluster_id );
     552fatfs_dmsg("\n[DBG] %s : core[%x,%d] access device for inode %x / cluster_id %d\n",
     553__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , inode , searched_cluster_id );
    544554
    545555        // get lba from cluster_id
     
    553563    }
    554564
    555     fatfs_dmsg("\n[DMSG] %s : core[%x,%d] exit for page %d / inode %x / mapper %x\n",
    556     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , index , inode , mapper );
     565fatfs_dmsg("\n[DBG] %s : core[%x,%d] exit for page %d / inode %x / mapper %x\n",
     566__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , index , inode , mapper );
    557567
    558568#if (CONFIG_FATFS_DEBUG & 0x1)
     
    584594    // - scan the directory entries in each 4 Kbytes page
    585595
    586     fatfs_dmsg("\n[DMSG] %s : enter for child <%s> in parent inode %l\n",
    587                __FUNCTION__ , name , XPTR( local_cxy , parent_inode ) );
     596fatfs_dmsg("\n[DBG] %s : enter for child <%s> in parent inode %l\n",
     597__FUNCTION__ , name , XPTR( local_cxy , parent_inode ) );
    588598
    589599    mapper_t * mapper = parent_inode->mapper;
     
    705715    if ( found == -1 )  // found end of directory => failure
    706716    {
    707         fatfs_dmsg("\n[DMSG] %s : exit / child <%s> not found in parent inode %l\n",
    708                    __FUNCTION__ , name , XPTR( local_cxy , parent_inode ) );
     717
     718fatfs_dmsg("\n[DBG] %s : exit / child <%s> not found in parent inode %l\n",
     719__FUNCTION__ , name , XPTR( local_cxy , parent_inode ) );
    709720
    710721        return ENOENT;
     
    723734        hal_remote_sw( XPTR( child_cxy , &child_ptr->extend ) , cluster );
    724735
    725         fatfs_dmsg("\n[DMSG] %s : exit / child <%s> found in parent inode %l\n",
    726                    __FUNCTION__ , name , XPTR( local_cxy , parent_inode ) );
     736fatfs_dmsg("\n[DBG] %s : exit / child <%s> found in parent inode %l\n",
     737__FUNCTION__ , name , XPTR( local_cxy , parent_inode ) );
    727738
    728739        return 0;
  • trunk/kernel/fs/vfs.c

    r406 r407  
    156156    error_t            error;
    157157
    158     vfs_dmsg("\n[INFO] %s : core[%x,%d] enter / dentry_xp = %l\n",
    159     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , dentry_xp );
     158vfs_dmsg("\n[DBG] %s : core[%x,%d] enter / dentry = %x in cluster %x\n",
     159__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, GET_PTR(dentry_xp), GET_CXY(dentry_xp) );
    160160 
    161161    // check fs type and get pointer on context
     
    229229    remote_spinlock_init( XPTR( local_cxy , &inode->main_lock ) );
    230230
    231     vfs_dmsg("\n[INFO] %s : core[%x,%d] exit / inode_xp = %l / dentry_xp = %l\n",
    232     __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, XPTR(local_cxy,inode), dentry_xp );
     231vfs_dmsg("\n[DBG] %s : core[%x,%d] exit / inode = %x in cluster %x\n",
     232__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, inode , local_cxy );
    233233 
    234234    // return extended pointer on inode
     
    262262                        xptr_t        child_xp )
    263263{
    264     vfs_dmsg("\n[INFO] %s : core[%x,%d] enter for <%s> / cycle %d\n",
    265     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , name , hal_time_stamp() );
     264vfs_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s> / cycle %d\n",
     265__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , name , hal_time_stamp() );
    266266
    267267    error_t error = 0;
     
    292292    }
    293293
    294     vfs_dmsg("\n[INFO] %s : core[%x,%d] exit for <%s> / cycle %d\n",
    295     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , name , hal_time_stamp() );
     294vfs_dmsg("\n[DBG] %s : core[%x,%d] exit for <%s> / cycle %d\n",
     295__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , name , hal_time_stamp() );
    296296
    297297    return error;
     
    413413
    414414    // display inode header
    415     printk("\n*** inode <%s> / inode_xp = %l / dentry_xp = %l ***\n",
    416            name , inode_xp , dentry_xp );
     415    printk("\n***** inode <%s> [%x in cluster %x]\n",
     416           name , GET_PTR(inode_xp) , GET_CXY(inode_xp) );
    417417
    418418    // display children from xhtab
     
    435435        kmem_req_t       req;        // request to kernel memory allocator
    436436
    437     vfs_dmsg("\n[INFO] %s : core[%x,%d] enter for <%s> / parent inode = %x / cycle %d\n",
    438     __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, name, parent, hal_time_stamp() );
     437vfs_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s> / parent inode = %x / cycle %d\n",
     438__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, name, parent, hal_time_stamp() );
    439439
    440440    // get pointer on context
     
    484484    *dentry_xp = XPTR( local_cxy , dentry );
    485485
    486     vfs_dmsg("\n[INFO] %s : core[%x,%d] exit for <%s> / dentry = %l / cycle %d\n",
    487     __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, name, *dentry_xp, hal_time_stamp() );
     486vfs_dmsg("\n[DBG] %s : core[%x,%d] exit for <%s> / dentry = %x in cluster %x / cycle %d\n",
     487__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, name, dentry, local_cxy , hal_time_stamp() );
    488488
    489489    return 0;
     
    586586//////////////////////////////////////////////////////////////////////////////////////////
    587587
    588 ////////////////////////////////////
    589 error_t vfs_open( xptr_t     cwd_xp,
    590                           char     * path,
    591                           uint32_t   flags,
    592                   uint32_t   mode,
    593                           xptr_t   * new_file_xp,
    594                   uint32_t * new_file_id )
     588//////////////////////////////////////
     589error_t vfs_open( process_t * process,
     590                          char      * path,
     591                          uint32_t    flags,
     592                  uint32_t    mode,
     593                          xptr_t    * new_file_xp,
     594                  uint32_t  * new_file_id )
    595595{
    596596    error_t       error;
     
    603603    uint32_t      file_id;      // created file descriptor index in reference fd_array
    604604
    605     vfs_dmsg("\n[INFO] %s : core[%x,%d] enter for <%s> / cycle %d\n",
    606     __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path, (uint32_t)hal_time_stamp() );
     605vfs_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s> / cycle %d\n",
     606__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path, (uint32_t)hal_time_stamp() );
    607607
    608608    // compute lookup working mode
     
    614614    // compute attributes for the created file
    615615    file_attr = 0;
    616     if( (flags & O_RDONLY ) == 0 )  file_attr |= FD_ATTR_READ_ENABLE;
    617     if( (flags & O_WRONLY ) == 0 )  file_attr |= FD_ATTR_WRITE_ENABLE;
     616    if( (flags & O_RDONLY ) == 0 )  file_attr |= FD_ATTR_WRITE_ENABLE;
     617    if( (flags & O_WRONLY ) == 0 )  file_attr |= FD_ATTR_READ_ENABLE;
    618618    if( (flags & O_SYNC   )      )  file_attr |= FD_ATTR_SYNC;
    619619    if( (flags & O_APPEND )      )  file_attr |= FD_ATTR_APPEND;
     
    621621
    622622    // get extended pointer on target inode
    623     error = vfs_lookup( cwd_xp , path , lookup_mode , &inode_xp );
     623    error = vfs_lookup( process->vfs_cwd_xp , path , lookup_mode , &inode_xp );
    624624
    625625    if( error ) return error;
     
    629629    inode_ptr = (vfs_inode_t *)GET_PTR( inode_xp );
    630630   
     631vfs_dmsg("\n[DBG] %s : core[%x,%d] found inode for <%s> in cluster %x / cycle %d\n",
     632__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path, inode_cxy , (uint32_t)hal_time_stamp() );
     633
    631634    // create a new file descriptor in cluster containing inode
    632635    if( inode_cxy == local_cxy )      // target cluster is local
     
    641644    if( error )  return error;
    642645
    643     // allocate and register a new file descriptor index in reference cluster fd_array
    644     error = process_fd_register( file_xp , &file_id );
     646    // allocate and register a new file descriptor index in reference process
     647    error = process_fd_register( process , file_xp , &file_id );
    645648
    646649    if( error ) return error;
    647650
    648     vfs_dmsg("\n[INFO] %s : core[%x,%d] exit for <%s> / file_xp = %l / cycle %d\n",
    649     __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path, file_xp, hal_time_stamp() );
     651vfs_dmsg("\n[DBG] %s : core[%x,%d] exit for <%s> / file = %x in cluster %x / cycle %d\n",
     652__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path,
     653GET_PTR(file_xp), GET_CXY(file_xp), hal_time_stamp() );
    650654
    651655    // success
     
    656660}  // end vfs_open()
    657661
    658 ////////////////////////////////////////////
    659 error_t vfs_user_move( bool_t   to_buffer,
    660                        xptr_t   file_xp,
    661                        void   * buffer,
    662                        uint32_t size )
    663 {
    664     assert( ( file_xp != XPTR_NULL ) , __FUNCTION__ , "file_xp == XPTR_NULL" );
     662//////////////////////////////////////
     663int vfs_user_move( bool_t   to_buffer,
     664                   xptr_t   file_xp,
     665                   void   * buffer,
     666                   uint32_t size )
     667{
     668    assert( ( file_xp != XPTR_NULL ) , __FUNCTION__ ,
     669    "file_xp == XPTR_NULL" );
    665670
    666671    cxy_t              file_cxy;     // remote file descriptor cluster
     
    678683    inode_type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type   ) );
    679684   
    680     // action depends on inode type
    681     if( inode_type == INODE_TYPE_FILE )
    682     {
    683         // get mapper pointer and file offset from file descriptor
    684         file_offset = hal_remote_lw( XPTR( file_cxy , &file_ptr->offset ) );
    685         mapper = (mapper_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) );
    686 
    687         // move data between mapper and buffer
    688         if( file_cxy == local_cxy )
    689         {
    690             error = mapper_move_user( mapper,
    691                                       to_buffer,
    692                                       file_offset,
    693                                       buffer,
    694                                       size );
    695         }
    696         else
    697         {
    698             rpc_mapper_move_buffer_client( file_cxy,
    699                                            mapper,
    700                                            to_buffer,
    701                                            true,          // user buffer
    702                                            file_offset,
    703                                            (uint64_t)(intptr_t)buffer,
    704                                            size,
    705                                            &error );
    706         }
    707 
    708         if( error ) return -1;
    709         else        return 0;
    710     }
    711     else
    712     {
    713         printk("\n[ERROR] in %s : inode is not a file", __FUNCTION__ );
    714         return -1;
    715     }
     685    assert( (inode_type == INODE_TYPE_FILE) , __FUNCTION__ ,
     686    "inode type is not INODE_TYPE_FILE" );
     687
     688    // get mapper pointer and file offset from file descriptor
     689    file_offset = hal_remote_lw( XPTR( file_cxy , &file_ptr->offset ) );
     690    mapper = (mapper_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) );
     691
     692    // move data between mapper and buffer
     693    if( file_cxy == local_cxy )
     694    {
     695        error = mapper_move_user( mapper,
     696                                  to_buffer,
     697                                  file_offset,
     698                                  buffer,
     699                                  size );
     700    }
     701    else
     702    {
     703        rpc_mapper_move_buffer_client( file_cxy,
     704                                       mapper,
     705                                       to_buffer,
     706                                       true,          // user buffer
     707                                       file_offset,
     708                                       (uint64_t)(intptr_t)buffer,
     709                                       size,
     710                                       &error );
     711    }
     712
     713    if( error ) return -1;
     714    else        return size;
     715
    716716}  // end vfs_user_move()
    717717
     
    905905    panic("not implemented");
    906906    return 0;
    907 }  // vfs_unlink()
    908 
    909 ///////////////////////////////////////
    910 error_t vfs_stat( xptr_t       file_xp,
    911                   vfs_stat_t * k_stat )
     907}
     908
     909////////////////////////////////////////
     910error_t vfs_stat( xptr_t        file_xp,
     911                  struct stat * k_stat )
    912912{
    913913    panic("not implemented");
     
    915915}
    916916
    917 ////////////////////////////////////////////
    918 error_t vfs_readdir( xptr_t         file_xp,
    919                      vfs_dirent_t * k_dirent )
     917/////////////////////////////////////////////
     918error_t vfs_readdir( xptr_t          file_xp,
     919                     struct dirent * k_dirent )
    920920{
    921921    panic("not implemented");
     
    10941094
    10951095    // display inode
    1096     nolock_printk("%s%s <%s> : inode = %l / mapper = %l / dentry = %l\n",
     1096    nolock_printk("%s%s <%s> : inode = %x / mapper = %x / cluster %x\n",
    10971097                  indent_str[indent], vfs_inode_type_str( inode_type ), name,
    1098                   inode_xp , XPTR( inode_cxy , mapper_ptr ) , dentry_xp );
     1098                  inode_ptr , mapper_ptr , inode_cxy );
    10991099
    11001100    // scan directory entries 
     
    11711171
    11721172    // get pointers on TXT0 chdev
    1173     xptr_t    txt0_xp  = chdev_dir.txt[0];
     1173    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
    11741174    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
    11751175    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     
    13381338    process = this->process;
    13391339
    1340     vfs_dmsg("\n[INFO] %s : core[%x,%d] enter for <%s> / cycle %d\n",
    1341     __FUNCTION__ , local_cxy , this->core->lid , pathname , hal_time_stamp() );
     1340vfs_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s> / cycle %d\n",
     1341__FUNCTION__ , local_cxy , this->core->lid , pathname , hal_time_stamp() );
    13421342
    13431343    // get extended pointer on first inode to search
     
    13621362        vfs_get_name_from_path( current , name , &next , &last );
    13631363
    1364         vfs_dmsg("\n[INFO] %s : core[%x,%d] look for <%s> / last = %d\n",
    1365         __FUNCTION__ , local_cxy , this->core->lid , name , last );
     1364vfs_dmsg("\n[DBG] %s : core[%x,%d] look for <%s> / last = %d\n",
     1365__FUNCTION__ , local_cxy , this->core->lid , name , last );
    13661366
    13671367        // search a child dentry matching name in parent inode
     
    13801380        if (found == false ) // child node not found in inode tree
    13811381        {
    1382             vfs_dmsg("\n[INFO] %s : core[%x,%d] miss <%s> => load it\n",
    1383             __FUNCTION__ , local_cxy , this->core->lid , name );
     1382
     1383vfs_dmsg("\n[DBG] %s : core[%x,%d] miss <%s> => load it\n",
     1384__FUNCTION__ , local_cxy , this->core->lid , name );
    13841385
    13851386            // release lock on parent inode
     
    14051406            if( error )
    14061407            {
    1407                 printk("\n[ERROR] in %s : no memory for inode %s in path %s\n",
     1408                printk("\n[ERROR] in %s : no memory for inode <%s> in path <%s>\n",
    14081409                __FUNCTION__ , name , pathname );
    14091410                return ENOMEM;
     
    14281429            if ( error )
    14291430            {
    1430                 printk("\n[ERROR] in %s : core[%x,%d] / <%s> not found in parent\n",
    1431                 __FUNCTION__ , local_cxy , this->core->lid , name );
     1431                printk("\n[ERROR] in %s : core[%x,%d] / <%s> node not found in <%s>\n",
     1432                __FUNCTION__ , local_cxy , this->core->lid , name , pathname );
    14321433                return ENOENT;
    14331434            }
     
    14641465            vfs_inode_lock( parent_xp );
    14651466
    1466             vfs_dmsg("\n[INFO] %s : core[%x,%d] created node <%s>\n",
    1467             __FUNCTION__ , local_cxy , this->core->lid , name );
     1467vfs_dmsg("\n[DBG] %s : core[%x,%d] created node <%s>\n",
     1468__FUNCTION__ , local_cxy , this->core->lid , name );
     1469
    14681470        }
    14691471
    1470         vfs_dmsg("\n[INFO] %s : core[%x,%d] found <%s> / parent = %l / child = %l\n",
    1471         __FUNCTION__ , local_cxy , this->core->lid , name , parent_xp , child_xp );
     1472vfs_dmsg("\n[DBG] %s : core[%x,%d] found <%s> / inode = %x in cluster %x\n",
     1473__FUNCTION__ , local_cxy , this->core->lid , name , GET_PTR(child_xp) , GET_CXY(child_xp) );
    14721474
    14731475        // TODO check access rights here [AG]
     
    14941496    vfs_inode_unlock( parent_xp );
    14951497
    1496     vfs_dmsg("\n[INFO] %s : exit <%s> found / inode = %l\n",
    1497                  __FUNCTION__ , pathname , child_xp );
     1498vfs_dmsg("\n[DBG] %s : core[%x,%d] exit for <%s> / inode = %x in cluster %x\n",
     1499__FUNCTION__,local_cxy,this->core->lid,pathname,GET_PTR(child_xp),GET_CXY(child_xp) );
    14981500
    14991501    // return searched pointer
     
    15931595    parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );
    15941596
    1595     vfs_dmsg("\n[INFO] %s : enter for <%s> / core[%x,%d] / child_cxy = %x / parent_xp = %l\n",
    1596     __FUNCTION__ , name , local_cxy , CURRENT_THREAD->core->lid , child_cxy , parent_xp );
     1597vfs_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s> / child_cxy = %x / parent_cxy = %x\n",
     1598__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , name , child_cxy , parent_cxy );
    15971599
    15981600    // 1. create dentry
     
    16041606                                   &dentry_xp );
    16051607
    1606         vfs_dmsg("\n[INFO] %s : dentry <%s> created in local cluster %x\n",
    1607         __FUNCTION__ , name , local_cxy );
     1608vfs_dmsg("\n[DBG] %s : dentry <%s> created in local cluster %x\n",
     1609__FUNCTION__ , name , local_cxy );
     1610
    16081611    }
    16091612    else                               // parent cluster is remote
     
    16161619                                      &error );
    16171620
    1618         vfs_dmsg("\n[INFO] %s : dentry <%s> created in remote cluster %x\n",
    1619         __FUNCTION__ , name , parent_cxy );
     1621vfs_dmsg("\n[DBG] %s : dentry <%s> created in remote cluster %x\n",
     1622__FUNCTION__ , name , parent_cxy );
     1623
    16201624    }
    16211625                                     
     
    16231627    {
    16241628        printk("\n[ERROR] in %s : cannot create dentry in cluster %x\n",
    1625                __FUNCTION__ , parent_cxy );
     1629        __FUNCTION__ , parent_cxy );
    16261630        return ENOMEM;
    16271631    }
     
    16451649                                  &inode_xp );
    16461650
    1647         vfs_dmsg("\n[INFO] %s : inode %l created in local cluster %x\n",
    1648                  __FUNCTION__ , inode_xp , local_cxy );
     1651vfs_dmsg("\n[DBG] %s : inode %x created in local cluster %x\n",
     1652__FUNCTION__ , GET_PTR(inode_xp) , local_cxy );
     1653
    16491654    }
    16501655    else                              // child cluster is remote
     
    16621667                                     &error );
    16631668
    1664         vfs_dmsg("\n[INFO] %s : inode %l created in remote cluster %x\n",
    1665                  __FUNCTION__ , inode_xp , child_cxy );
     1669vfs_dmsg("\n[DBG] %s : inode %x created in remote cluster %x\n",
     1670__FUNCTION__ , GET_PTR(inode_xp) , child_cxy );
     1671
    16661672    }
    16671673                                     
     
    16821688    hal_remote_swd( XPTR( dentry_cxy , &dentry_ptr->child_xp ) , inode_xp );
    16831689
    1684     vfs_dmsg("\n[INFO] %s : exit in cluster %x for <%s>\n",
    1685     __FUNCTION__ , local_cxy , name );
     1690vfs_dmsg("\n[DBG] %s : exit in cluster %x for <%s>\n",
     1691__FUNCTION__ , local_cxy , name );
    16861692
    16871693    // success : return extended pointer on child inode
     
    17071713    assert( (mapper != NULL) , __FUNCTION__ , "no mapper for page\n" );
    17081714
    1709     vfs_dmsg("\n[DMSG] %s : enters for page %d / inode_cxy = %x / inode_ptr = %x\n",
    1710     __FUNCTION__ , page->index , local_cxy , mapper->inode );
     1715vfs_dmsg("\n[DBG] %s : core[%x,%d] enters for page %d / mapper = %x / inode = %x\n",
     1716__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid , page->index , mapper, mapper->inode );
    17111717
    17121718    // get FS type
     
    17331739    }
    17341740
    1735     vfs_dmsg("\n[DMSG] %s : exit for page %d / inode_cxy = %x / inode_ptr = %x\n",
    1736     __FUNCTION__ , page->index , local_cxy , mapper->inode );
     1741vfs_dmsg("\n[DBG] %s : core[%x,%d] exit for page %d / mapper = %x / inode = %x\n",
     1742__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, page->index, mapper, mapper->inode );
    17371743
    17381744    return error;
     
    17531759    assert( (mapper != NULL) , __FUNCTION__ , "mapper pointer is NULL\n" );
    17541760
    1755     vfs_dmsg("\n[INFO] %s : core[%x,%d] enter for inode %l / cycle %d\n",
    1756     __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, XPTR(local_cxy , inode) );
     1761vfs_dmsg("\n[DBG] %s : core[%x,%d] enter for inode %x in cluster %x/ cycle %d\n",
     1762__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, inode , local_cxy , hal_time_stamp() );
    17571763
    17581764    // compute number of pages
     
    17701776    }
    17711777
    1772     vfs_dmsg("\n[INFO] %s : core[%x,%d] exit for inode %l / cycle %d\n",
    1773     __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, XPTR(local_cxy , inode) );
     1778vfs_dmsg("\n[DBG] %s : core[%x,%d] exit for inode %x in cluster %x / cycle %d\n",
     1779__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, inode , local_cxy , hal_time_stamp() );
    17741780
    17751781    return 0;
  • trunk/kernel/fs/vfs.h

    r317 r407  
    3838#include <xhtab.h>
    3939#include <errno.h>
    40 #include <metafs.h>
    41 
     40#include <shared_syscalls.h>
    4241#include <fatfs.h>
    4342#include <ramfs.h>
     
    235234typedef enum
    236235{
    237     VFS_SEEK_SET,
    238     VFS_SEEK_CUR,
    239     VFS_SEEK_END,
    240 }
    241 vfs_lseek_cmd_t;
    242 
    243 typedef enum
    244 {
    245236    FD_ATTR_READ_ENABLE    = 0x01,     /*! read access possible                         */
    246237    FD_ATTR_WRITE_ENABLE   = 0x02,     /*! write access possible                        */
     
    267258vfs_file_t;
    268259
    269 /******************************************************************************************
    270  * This structure define the informations associated to a file descriptor,
    271  * returned to user space by the stat() system call.
    272  *****************************************************************************************/
    273 
    274 typedef struct vfs_stat_s
    275 {
    276         uint32_t    dev;        /*! ID of device containing file                             */
    277         uint32_t    ino;        /*! inode number                                             */
    278         uint32_t    mode;       /*! protection                                               */
    279         uint32_t    nlink;      /*! number of hard links                                     */
    280         uint32_t    uid;        /*! user ID of owner                                         */
    281         uint32_t    gid;        /*! group ID of owner                                        */
    282         uint32_t    rdev;       /*! device ID (if special file)                              */
    283         uint64_t    size;       /*! total size, in bytes                                     */
    284         uint32_t    blksize;    /*! blocksize for file system I/O                            */
    285         uint32_t    blocks;     /*! number of 512B blocks allocated                          */
    286         uint64_t    atime;      /*! time of last access                                      */
    287         uint64_t    mtime;      /*! time of last modification                                */
    288         uint64_t    ctime;      /*! time of last status change                               */
    289 }
    290 vfs_stat_t;
    291 
    292 /*********************************************************************************************
    293  * This structure defines the information associated to a directory entry,
    294  * returned to user space by the readdir() system call.
    295  ********************************************************************************************/
    296 
    297 typedef struct vfs_dirent_s
    298 {
    299     uint32_t    inum;                               /*! inode identifier                    */
    300     uint32_t    type;                               /*! inode type                          */
    301     char        name[CONFIG_VFS_MAX_NAME_LENGTH];   /*! dentry name                         */
    302 }
    303 vfs_dirent_t;
    304 
    305 
    306260
    307261/*****************************************************************************************/
     
    503457error_t vfs_inode_unlink( vfs_inode_t * inode );
    504458
    505 /******************************************************************************************
    506  * This function TODO                                                         
    507  *****************************************************************************************/
    508 error_t vfs_inode_stat( vfs_inode_t * inode,
    509                         uint32_t      inum );
    510 
    511 /******************************************************************************************
    512  * This function TODO                                                         
    513  *****************************************************************************************/
    514 error_t vfs_icache_del( vfs_inode_t * inode );
    515 
    516 
    517 /******************************************************************************************
    518  * This function TODO  Pourquoi 2 arguments ?
    519  *****************************************************************************************/
    520 error_t vfs_stat_inode( vfs_inode_t * inode,
    521                         uint32_t      inum );
    522 
    523459
    524460/*****************************************************************************************/
     
    643579 * @ lookup_mode : flags defining the working mode (defined above in this file).
    644580 * @ inode_xp    : [out] buffer for extended pointer on searched inode.
    645  * @ return 0 if success / ENOENT if inode not found , EACCES if permissopn denied,
    646  *                        EAGAIN if a new complete lookup must be made
     581 * @ return 0 if success / ENOENT if inode not found , EACCES if permisson denied,
     582 *                         EAGAIN if a new complete lookup must be made
    647583 *****************************************************************************************/
    648584error_t vfs_lookup( xptr_t             cwd_xp,
     
    653589/******************************************************************************************
    654590 * This function creates a new couple dentry/inode, and insert it in the Inode-Tree.
    655  * It can be executed by any thread running in any cluster ( can be differente from both
     591 * It can be executed by any thread running in any cluster (can be different from both
    656592 * the child cluster and the parent cluster), as it uses the rpc_dentry_create_client()
    657593 * and rpc_inode_create client() if required. This is done in three steps:
     
    707643/******************************************************************************************
    708644 * This function allocates a vfs_file_t structure in the cluster containing the inode
    709  * associated to the file identified by <cwd_xp> & <path>.
    710  * It initializes it, register it in the reference process fd_array, and returns both
    711  * the extended pointer on the remote file descriptor, and the index in the fd_array.
     645 * associated to the file identified by the <cwd_xp> & <path> arguments.
     646 * It initializes it, register it in the reference process fd_array identified by the
     647 * <process> argument, and returns both the extended pointer on the file descriptor,
     648 * and the allocated index in the fd_array.
    712649 * The pathname can be relative to current directory or absolute.
    713650 * If the inode does not exist in the inode cache, it try to find the file on the mounted
    714651 * device, and creates an inode on a pseudo randomly selected cluster if found.
    715652 * It the requested file does not exist on device, it creates a new inode if the
    716  * O_CREAT flag is set and return an error otherwise.
    717  ******************************************************************************************
    718  * @ cwd_xp      : extended pointer on current working directory file descriptor.
     653 * O_CREAT flag is set, and return an error otherwise.
     654 ******************************************************************************************
     655 * @ process     : local pointer on local process descriptor copy.
    719656 * @ path        : file pathname (absolute or relative to current directory).
    720  * @ flags       : defined above 
     657 * @ flags       : defined above.
    721658 * @ mode        : access rights (as defined by chmod)
    722659 * @ file_xp     : [out] buffer for extended pointer on created remote file descriptor.
     
    724661 * @ return 0 if success / return non-zero if error.
    725662 *****************************************************************************************/
    726 error_t vfs_open( xptr_t     cwd_xp,
    727                           char     * path,
    728                           uint32_t   flags,
    729                   uint32_t   mode,
    730                           xptr_t   * file_xp,
    731                           uint32_t * file_id );
     663error_t vfs_open( struct process_s * process,
     664                          char             * path,
     665                          uint32_t           flags,
     666                  uint32_t           mode,
     667                          xptr_t           * file_xp,
     668                          uint32_t         * file_id );
    732669
    733670/******************************************************************************************
     
    735672 * <file_xp> argument, and a - possibly distributed - user space <buffer>, taken into
    736673 * account the offset in <file_xp>. The transfer direction is defined by <to_buffer>.
    737  * This function is called by the elf_load_process() function.
     674 * It is called by the sys_read() and sys_write() functions.
    738675 ******************************************************************************************
    739676 * @ to_buffer : mapper -> buffer if true / buffer -> mapper if false.
     
    741678 * @ buffer    : user space pointer on buffer (can be physically distributed).
    742679 * @ size      : requested number of bytes from offset.
    743  * @ returns 0 f success / -1 if error.
    744  *****************************************************************************************/
    745 error_t vfs_user_move( bool_t   to_buffer,
    746                        xptr_t   file_xp,
    747                        void   * buffer,
    748                        uint32_t size );
     680 * @ returns number of bytes actually moved if success / -1 if error.
     681 *****************************************************************************************/
     682int vfs_user_move( bool_t   to_buffer,
     683                   xptr_t   file_xp,
     684                   void   * buffer,
     685                   uint32_t size );
    749686
    750687/******************************************************************************************
     
    752689 * <file_xp> argument, and a - possibly remote - kernel <buffer_xp>, taken into
    753690 * account the offset in <file_xp>. The transfer direction is defined by <to_buffer>.
    754  * This function is called by the  system calls.
     691 * It is called by the elf_load_process() function.
    755692 ******************************************************************************************
    756693 * @ to_buffer : mapper -> buffer if true / buffer -> mapper if false.
     
    758695 * @ buffer_xp : user space pointer on buffer (can be physically distributed).
    759696 * @ size      : requested number of bytes from offset.
    760  * @ returns number of bytes actually transfered / -1 if error.
     697 * @ returns 0 if success / -1 if error.
    761698 *****************************************************************************************/
    762699error_t vfs_kernel_move( bool_t   to_buffer,
     
    814751 ******************************************************************************************
    815752 * @ file_xp    : extended pointer on the file descriptor of the searched directory .
    816  * @ k_dirent   : local pointer on the dirent_t structure in kernel space.
     753 * @ k_stat     : local pointer on the stat structure in kernel space.
    817754 * @ returns 0 if success / -1 if error.
    818755 *****************************************************************************************/
    819 error_t vfs_stat( xptr_t       file_xp,
    820                   vfs_stat_t * k_stat );
     756error_t vfs_stat( xptr_t        file_xp,
     757                  struct stat * k_stat );
    821758
    822759/******************************************************************************************
     
    826763 ******************************************************************************************
    827764 * @ file_xp    : extended pointer on the file descriptor of the searched directory .
    828  * @ k_dirent   : local pointer on the dirent_t structure in kernel space.
     765 * @ k_dirent   : local pointer on the dirent structure in kernel space.
    829766 * @ returns 0 if success / -1 if error.
    830767 *****************************************************************************************/
    831 error_t vfs_readdir( xptr_t         file_xp,
    832                      vfs_dirent_t * k_dirent );
     768error_t vfs_readdir( xptr_t          file_xp,
     769                     struct dirent * k_dirent );
    833770
    834771/******************************************************************************************
  • trunk/kernel/kern/chdev.c

    r317 r407  
    2525#include <hal_types.h>
    2626#include <hal_special.h>
     27#include <hal_irqmask.h>
    2728#include <printk.h>
    2829#include <boot_info.h>
    2930#include <xlist.h>
    3031#include <kmem.h>
     32#include <scheduler.h>
    3133#include <thread.h>
    3234#include <rpc.h>
     
    3739extern chdev_directory_t    chdev_dir;   // allocated in kernel_init.c
    3840
     41#if CONFIG_READ_DEBUG
     42extern uint32_t enter_chdev_cmd;
     43extern uint32_t exit_chdev_cmd;
     44extern uint32_t enter_chdev_server;
     45extern uint32_t exit_chdev_server;
     46#endif
    3947
    4048////////////////////////////////////////////
     
    105113}
    106114
    107 ////////////////////////////////////////////////
    108 void chdev_register_command( xptr_t     chdev_xp,
    109                              thread_t * thread )
    110 {
    111     thread_t * thread_ptr = CURRENT_THREAD;
     115//////////////////////////////////////////////////
     116void chdev_register_command( xptr_t     chdev_xp )
     117{
     118    thread_t * server_ptr;    // local pointer on server thread associated to chdev
     119    core_t   * core_ptr;      // local pointer on core running the server thread
     120    uint32_t   lid;           // core running the server thread local index
     121    xptr_t     lock_xp;       // extended pointer on lock protecting the chdev queue
     122    uint32_t   modified;      // non zero if the server thread state was modified
     123    uint32_t   save_sr;       // for critical section
     124
     125    thread_t * this = CURRENT_THREAD;
     126
     127chdev_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) enter / cycle %d\n",
     128__FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type) , hal_time_stamp() );
    112129
    113130    // get device descriptor cluster and local pointer
     
    116133
    117134    // build extended pointers on client thread xlist and device root
    118     xptr_t  xp_list = XPTR( local_cxy , &thread_ptr->wait_list );
    119     xptr_t  xp_root = XPTR( chdev_cxy , &chdev_ptr->wait_root );
    120 
    121     // get lock protecting queue
    122     remote_spinlock_lock( XPTR( chdev_cxy , &chdev_ptr->wait_lock ) );
     135    xptr_t  list_xp = XPTR( local_cxy , &this->wait_list );
     136    xptr_t  root_xp = XPTR( chdev_cxy , &chdev_ptr->wait_root );
     137
     138    // get local pointer on server thread
     139    server_ptr = (thread_t *)hal_remote_lpt( XPTR( chdev_cxy , &chdev_ptr->server) );
     140
     141chdev_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) / server_cxy %x / server_ptr %x / server_type %\n",
     142__FUNCTION__, local_cxy, this->core->lid, server_cxy, server_ptr,
     143thread_type_str( hal_remote_lw( XPTR( server_cxy , &server_ptr->type) ) ) );
     144
     145    // build extended pointer on chdev lock protecting queue
     146    lock_xp = XPTR( chdev_cxy , &chdev_ptr->wait_lock );
     147
     148    // get local pointer on core running the server thread
     149    core_ptr = (core_t *)hal_remote_lpt( XPTR( chdev_cxy , &server_ptr->core ) );
     150
     151    // get core local index
     152    lid = hal_remote_lw( XPTR( chdev_cxy , &core_ptr->lid ) );
     153
     154    // enter critical section
     155    hal_disable_irq( &save_sr );
    123156
    124157    // register client thread in waiting queue
    125     xlist_add_last( xp_root , xp_list );
     158    remote_spinlock_lock( lock_xp );
     159    xlist_add_last( root_xp , list_xp );
     160    remote_spinlock_unlock( lock_xp );
    126161
    127162    // unblock server thread
    128     thread_unblock( XPTR( chdev_cxy , &chdev_ptr->server ) , THREAD_BLOCKED_DEV_QUEUE );
    129 
    130     // release lock
    131     remote_spinlock_unlock( XPTR( chdev_cxy , &chdev_ptr->wait_lock ) );
    132 
    133     // client thread goes to blocked state and deschedule
    134     thread_block( thread_ptr , THREAD_BLOCKED_IO );
    135     sched_yield( NULL );
     163    modified = thread_unblock( XPTR( chdev_cxy , server_ptr ), THREAD_BLOCKED_DEV_QUEUE );
     164
     165    // send IPI to core running the server thread
     166    if( modified ) dev_pic_send_ipi( chdev_cxy , lid );
     167   
     168    // block client thread
     169    assert( thread_can_yield( this ) , __FUNCTION__ , "illegal sched_yield\n" );
     170
     171chdev_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) deschedules / cycle %d\n",
     172__FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type) , hal_time_stamp() );
     173
     174    thread_block( CURRENT_THREAD , THREAD_BLOCKED_IO );
     175    sched_yield();
     176
     177chdev_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) resumes / cycle %d\n",
     178__FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type) , hal_time_stamp() );
     179
     180    // exit critical section
     181    hal_restore_irq( save_sr );
    136182
    137183}  // end chdev_register_command()
     
    143189    cxy_t           client_cxy;   // cluster of client thread
    144190    thread_t      * client_ptr;   // local pointer on client thread
    145     thread_t      * server;       // local pointer on this thread
     191    thread_t      * server;       // local pointer on server thread
    146192    xptr_t          root_xp;      // extended pointer on device waiting queue root
     193    xptr_t          lock_xp;      // extended pointer on lock ptotecting chdev queue
    147194
    148195    server = CURRENT_THREAD;
    149196
     197chdev_dmsg("\n[DBG] %s : enter / server = %x / chdev = %x / cycle %d\n",
     198__FUNCTION__ , server , chdev , hal_time_stamp() );
     199
    150200    root_xp = XPTR( local_cxy , &chdev->wait_root );
    151 
    152     // take the lock protecting the chdev waiting queue, before entering the
    153         // infinite loop handling commands registered in this queue.
    154     // In the loop, the lock is released during the handling of one command.
    155 
    156     remote_spinlock_lock( XPTR( local_cxy , &chdev->wait_lock ) );
    157 
     201    lock_xp = XPTR( local_cxy , &chdev->wait_lock );
     202
     203        // This infinite loop is executed by the DEV thread
     204    // to handle commands registered in the chdev queue.
    158205    while( 1 )
    159206    {
     207        // get the lock protecting the waiting queue
     208        remote_spinlock_lock( lock_xp );
     209
    160210        // check waiting queue state
    161         if( xlist_is_empty( root_xp ) ) // block and deschedule if waiting queue empty
     211        if( xlist_is_empty( root_xp ) ) // waiting queue empty
    162212        {
    163213            // release lock
    164             remote_spinlock_unlock( XPTR( local_cxy , &chdev->wait_lock ) );
     214            remote_spinlock_unlock( lock_xp );
     215
     216chdev_dmsg("\n[DBG] %s : thread %x deschedule /cycle %d\n",
     217__FUNCTION__ , server , hal_time_stamp() );
    165218
    166219            // block and deschedule
    167220            thread_block( server , THREAD_BLOCKED_DEV_QUEUE );
    168             sched_yield( NULL );
     221            sched_yield();
     222
     223chdev_dmsg("\n[DBG] %s : thread %x resume /cycle %d\n",
     224__FUNCTION__ , server , hal_time_stamp() );
     225
    169226        }
    170         else
     227        else                            // waiting queue not empty
    171228        {
     229
     230#if CONFIG_READ_DEBUG
     231enter_chdev_server = hal_time_stamp();
     232#endif
    172233            // release lock
    173             remote_spinlock_unlock( XPTR( local_cxy , &chdev->wait_lock ) );
     234            remote_spinlock_unlock( lock_xp );
     235
     236            // get extended pointer on first client thread
     237            client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list );
     238
     239            // get client thread cluster, local pointer, and identifier
     240            client_cxy = GET_CXY( client_xp );
     241            client_ptr = (thread_t *)GET_PTR( client_xp );
     242
     243            // call driver command function to execute I/O operation
     244            chdev->cmd( client_xp );
     245       
     246            // remove the client thread from waiting queue
     247            remote_spinlock_lock( lock_xp );
     248            xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) );
     249            remote_spinlock_unlock( lock_xp );
     250
     251chdev_dmsg("\n[DBG] %s : thread %x complete operation for client %x / cycle %d\n",
     252__FUNCTION__ , server , client_ptr , hal_time_stamp() );
     253
     254#if CONFIG_READ_DEBUG
     255exit_chdev_server = hal_time_stamp();
     256#endif
     257
    174258        }
    175 
    176         // get extended pointer on first client thread
    177         client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list );
    178 
    179         // call driver command function to execute I/O operation
    180         chdev->cmd( client_xp );
    181        
    182         // get client thread cluster and local pointer
    183         client_cxy = GET_CXY( client_xp );
    184         client_ptr = (thread_t *)GET_PTR( client_xp );
    185 
    186         // take the lock, and remove the client thread from waiting queue
    187         remote_spinlock_lock( XPTR( local_cxy , &chdev->wait_lock ) );
    188         xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) );
    189 
    190259    }  // end while
    191 
    192260}  // end chdev_sequencial_server()
    193261
     
    197265    cxy_t     iob_cxy  = GET_CXY( chdev_dir.iob );
    198266    chdev_t * iob_ptr  = (chdev_t *)GET_PTR( chdev_dir.iob );
    199     xptr_t    iob_base = hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) );
     267    uint32_t  iob_base = (uint32_t)hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) );
    200268
    201269    cxy_t     pic_cxy  = GET_CXY( chdev_dir.pic );
    202270    chdev_t * pic_ptr  = (chdev_t *)GET_PTR( chdev_dir.pic );
    203     xptr_t    pic_base = hal_remote_lwd( XPTR( pic_cxy , &pic_ptr->base ) );
    204 
    205     cxy_t     txt0_cxy  = GET_CXY( chdev_dir.txt[0] );
    206     chdev_t * txt0_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt[0] );
    207     xptr_t    txt0_base = hal_remote_lwd( XPTR( txt0_cxy , &txt0_ptr->base ) );
    208 
    209     cxy_t     txt1_cxy  = GET_CXY( chdev_dir.txt[1] );
    210     chdev_t * txt1_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt[1] );
    211     xptr_t    txt1_base = hal_remote_lwd( XPTR( txt1_cxy , &txt1_ptr->base ) );
    212 
    213     cxy_t     txt2_cxy  = GET_CXY( chdev_dir.txt[2] );
    214     chdev_t * txt2_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt[2] );
    215     xptr_t    txt2_base = hal_remote_lwd( XPTR( txt2_cxy , &txt2_ptr->base ) );
     271    uint32_t  pic_base = (uint32_t)hal_remote_lwd( XPTR( pic_cxy , &pic_ptr->base ) );
     272
     273    cxy_t     txt0_tx_cxy  = GET_CXY( chdev_dir.txt_tx[0] );
     274    chdev_t * txt0_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_tx[0] );
     275    uint32_t  txt0_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt0_tx_cxy , &txt0_tx_ptr->base ) );
     276
     277    cxy_t     txt0_rx_cxy  = GET_CXY( chdev_dir.txt_rx[0] );
     278    chdev_t * txt0_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_rx[0] );
     279    uint32_t  txt0_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt0_rx_cxy , &txt0_rx_ptr->base ) );
     280
     281    cxy_t     txt1_tx_cxy  = GET_CXY( chdev_dir.txt_tx[1] );
     282    chdev_t * txt1_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_tx[1] );
     283    uint32_t  txt1_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt1_tx_cxy , &txt1_tx_ptr->base ) );
     284
     285    cxy_t     txt1_rx_cxy  = GET_CXY( chdev_dir.txt_rx[1] );
     286    chdev_t * txt1_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_rx[1] );
     287    uint32_t  txt1_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt1_rx_cxy , &txt1_rx_ptr->base ) );
     288
     289    cxy_t     txt2_tx_cxy  = GET_CXY( chdev_dir.txt_tx[2] );
     290    chdev_t * txt2_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_tx[2] );
     291    uint32_t  txt2_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt2_tx_cxy , &txt2_tx_ptr->base ) );
     292
     293    cxy_t     txt2_rx_cxy  = GET_CXY( chdev_dir.txt_rx[2] );
     294    chdev_t * txt2_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.txt_rx[2] );
     295    uint32_t  txt2_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt2_rx_cxy , &txt2_rx_ptr->base ) );
    216296
    217297    cxy_t     ioc_cxy  = GET_CXY( chdev_dir.ioc[0] );
    218298    chdev_t * ioc_ptr  = (chdev_t *)GET_PTR( chdev_dir.ioc[0] );
    219     xptr_t    ioc_base = hal_remote_lwd( XPTR( ioc_cxy , &ioc_ptr->base ) );
     299    uint32_t  ioc_base = (uint32_t)hal_remote_lwd( XPTR( ioc_cxy , &ioc_ptr->base ) );
    220300
    221301    cxy_t     fbf_cxy  = GET_CXY( chdev_dir.fbf[0] );
    222302    chdev_t * fbf_ptr  = (chdev_t *)GET_PTR( chdev_dir.fbf[0] );
    223     xptr_t    fbf_base = hal_remote_lwd( XPTR( fbf_cxy , &fbf_ptr->base ) );
    224 
    225     cxy_t     nic_rx_cxy  = GET_CXY( chdev_dir.nic_rx[0] );
    226     chdev_t * nic_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.nic_rx[0] );
    227     xptr_t    nic_rx_base = hal_remote_lwd( XPTR( nic_rx_cxy , &nic_rx_ptr->base ) );
    228 
    229     cxy_t     nic_tx_cxy  = GET_CXY( chdev_dir.nic_tx[0] );
    230     chdev_t * nic_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.nic_tx[0] );
    231     xptr_t    nic_tx_base = hal_remote_lwd( XPTR( nic_tx_cxy , &nic_tx_ptr->base ) );
     303    uint32_t  fbf_base = (uint32_t)hal_remote_lwd( XPTR( fbf_cxy , &fbf_ptr->base ) );
     304
     305    cxy_t     nic0_rx_cxy  = GET_CXY( chdev_dir.nic_rx[0] );
     306    chdev_t * nic0_rx_ptr  = (chdev_t *)GET_PTR( chdev_dir.nic_rx[0] );
     307    uint32_t  nic0_rx_base = (uint32_t)hal_remote_lwd( XPTR( nic0_rx_cxy , &nic0_rx_ptr->base ) );
     308
     309    cxy_t     nic0_tx_cxy  = GET_CXY( chdev_dir.nic_tx[0] );
     310    chdev_t * nic0_tx_ptr  = (chdev_t *)GET_PTR( chdev_dir.nic_tx[0] );
     311    uint32_t  nic0_tx_base = (uint32_t)hal_remote_lwd( XPTR( nic0_tx_cxy , &nic0_tx_ptr->base ) );
    232312
    233313    printk("\n***** external chdev directory in cluster %x\n"
    234            "  - iob       = %l / base = %l\n"
    235            "  - pic       = %l / base = %l\n"
    236            "  - txt[0]    = %l / base = %l\n"
    237            "  - txt[1]    = %l / base = %l\n"
    238            "  - txt[2]    = %l / base = %l\n"
    239            "  - ioc[0]    = %l / base = %l\n"
    240            "  - fbf[0]    = %l / base = %l\n"
    241            "  - nic_rx[0] = %l / base = %l\n"
    242            "  - nic_tx[0] = %l / base = %l\n",
     314           "  - iob       : cxy = %X / ptr = %X / base = %X\n"
     315           "  - pic       : cxy = %X / ptr = %X / base = %X\n"
     316           "  - ioc       : cxy = %X / ptr = %X / base = %X\n"
     317           "  - fbf       : cxy = %X / ptr = %X / base = %X\n"
     318           "  - txt_rx[0] : cxy = %X / ptr = %X / base = %X\n"
     319           "  - txt_tx[0] : cxy = %X / ptr = %X / base = %X\n"
     320           "  - txt_rx[1] : cxy = %X / ptr = %X / base = %X\n"
     321           "  - txt_tx[1] : cxy = %X / ptr = %X / base = %X\n"
     322           "  - txt_rx[2] : cxy = %X / ptr = %X / base = %X\n"
     323           "  - txt_tx[2] : cxy = %X / ptr = %X / base = %X\n"
     324           "  - nic_rx[0] : cxy = %X / ptr = %X / base = %X\n"
     325           "  - nic_tx[0] : cxy = %X / ptr = %X / base = %X\n",
    243326           local_cxy,
    244            chdev_dir.iob, iob_base,
    245            chdev_dir.pic, pic_base,
    246            chdev_dir.txt[0], txt0_base,
    247            chdev_dir.txt[1], txt1_base,
    248            chdev_dir.txt[2], txt2_base,
    249            chdev_dir.ioc[0], ioc_base,
    250            chdev_dir.fbf[0], fbf_base,
    251            chdev_dir.nic_rx[0], nic_rx_base,
    252            chdev_dir.nic_tx[0], nic_tx_base );
     327           iob_cxy , iob_ptr , iob_base ,
     328           pic_cxy , pic_ptr , pic_base ,
     329           ioc_cxy , ioc_ptr , ioc_base ,
     330           fbf_cxy , fbf_ptr , fbf_base ,
     331           txt0_rx_cxy , txt0_rx_ptr , txt0_rx_base ,
     332           txt0_tx_cxy , txt0_tx_ptr , txt0_tx_base ,
     333           txt1_rx_cxy , txt1_rx_ptr , txt1_rx_base ,
     334           txt1_tx_cxy , txt1_tx_ptr , txt1_tx_base ,
     335           txt2_rx_cxy , txt2_rx_ptr , txt2_rx_base ,
     336           txt2_tx_cxy , txt2_tx_ptr , txt2_tx_base ,
     337           nic0_rx_cxy , nic0_rx_ptr , nic0_rx_base ,
     338           nic0_tx_cxy , nic0_tx_ptr , nic0_tx_base );
    253339
    254340}  // end chdev_dir_display()
  • trunk/kernel/kern/chdev.h

    r346 r407  
    6666
    6767/******************************************************************************************
    68  * This define the generic prototypes for the two functions that must be defined
    69  * by all drivers implementing a generic device:
    70  * - "cmd"     : start an I/O operation.
     68 * This define the generic prototypes for the three functions that must be defined
     69 * by the drivers implementing a generic device:
     70 * - "cmd"     : start a blocking I/O operation.
    7171 * - "isr"     : complete an I/O operation.
    72  * The "cmd" and "isr" are registered in the generic chdev descriptor at kernel init,
    73  * and are called to start and complete an I/O operation. 
     72 * - "aux"     : not for all drivers (implement special functions)
     73 * The "cmd", "isr", and "aux" driver functions are registered in the generic chdev
     74 * descriptor at kernel init, and are called to start and complete an I/O operation. 
    7475*****************************************************************************************/
    7576
     
    7778typedef void (dev_cmd_t) ( xptr_t thread ); 
    7879typedef void (dev_isr_t) ( struct chdev_s * dev ); 
     80typedef void (dev_aux_t) ( void * args ); 
    7981
    8082/******************************************************************************************
     
    121123        uint32_t             impl;        /*! peripheral inplementation subtype              */
    122124    uint32_t             channel;     /*! channel index                                  */
    123     bool_t               is_rx;       /*! relevant for NIC peripheral channels only      */
     125    bool_t               is_rx;       /*! relevant for NIC and TXT peripherals           */
    124126        xptr_t               base;        /*! extended pointer on channel device segment     */
    125127    char                 name[16];    /*! name (required by DEVFS)                       */
    126128
    127     dev_cmd_t          * cmd;         /*! local pointer on driver command function       */
    128     dev_isr_t          * isr;         /*! local pointer on driver ISR function           */ 
     129    dev_cmd_t          * cmd;         /*! local pointer on driver CMD function           */
     130    dev_isr_t          * isr;         /*! local pointer on driver ISR function           */
     131    dev_aux_t          * aux;         /*! local pointer on driver AUX function           */
     132
    129133    struct thread_s    * server;      /*! local pointer on associated server thread      */
    130134
     
    165169    xptr_t   pic;                                // external / single channel / shared
    166170
    167     xptr_t   txt[CONFIG_MAX_TXT_CHANNELS];       // external / multi-channels / shared
    168171    xptr_t   ioc[CONFIG_MAX_IOC_CHANNELS];       // external / multi-channels / shared
    169172    xptr_t   fbf[CONFIG_MAX_FBF_CHANNELS];       // external / multi-channels / shared
     173    xptr_t   txt_rx[CONFIG_MAX_TXT_CHANNELS];    // external / multi-channels / shared
     174    xptr_t   txt_tx[CONFIG_MAX_TXT_CHANNELS];    // external / multi-channels / shared
    170175    xptr_t   nic_rx[CONFIG_MAX_NIC_CHANNELS];    // external / multi-channels / shared
    171176    xptr_t   nic_tx[CONFIG_MAX_NIC_CHANNELS];    // external / multi-channels / shared
     
    211216
    212217/******************************************************************************************
    213  * This function registers a local client thread in the waiting queue of a remote
     218 * This function registers the calling thread in the waiting queue of a remote
    214219 * chdev descriptor, activates (i.e. unblock) the server thread associated to chdev,
    215220 * and blocks itself on the THREAD_BLOCKED_IO condition.
    216221 ******************************************************************************************
    217222 * @ chdev_xp  : extended pointer on remote chdev descriptor.
    218  * @ thread    : local pointer on client thread.
    219  *****************************************************************************************/
    220 void chdev_register_command( xptr_t            chdev_xp,
    221                              struct thread_s * thread );
     223 *****************************************************************************************/
     224void chdev_register_command( xptr_t chdev_xp );
    222225
    223226/******************************************************************************************
  • trunk/kernel/kern/cluster.c

    r406 r407  
    2929#include <hal_special.h>
    3030#include <hal_ppm.h>
     31#include <remote_fifo.h>
    3132#include <printk.h>
    3233#include <errno.h>
     
    7778    // initialize cluster local parameters
    7879        cluster->cores_nr        = info->cores_nr;
    79     cluster->cores_in_kernel = 0;
    8080
    8181    // initialize the lock protecting the embedded kcm allocator
    8282        spinlock_init( &cluster->kcm_lock );
    8383
    84     cluster_dmsg("\n[DMSG] %s for cluster %x enters\n",
    85                  __FUNCTION__ , local_cxy );
     84cluster_dmsg("\n[DBG] %s for cluster %x enters\n",
     85__FUNCTION__ , local_cxy );
    8686
    8787    // initialises DQDT
     
    102102    }
    103103
    104     cluster_dmsg("\n[DMSG] %s : PPM initialized in cluster %x at cycle %d\n",
    105                  __FUNCTION__ , local_cxy , hal_get_cycles() );
     104cluster_dmsg("\n[DBG] %s : PPM initialized in cluster %x at cycle %d\n",
     105__FUNCTION__ , local_cxy , hal_get_cycles() );
    106106
    107107    // initialises embedded KHM
    108108        khm_init( &cluster->khm );
    109109
    110     cluster_dmsg("\n[DMSG] %s : KHM initialized in cluster %x at cycle %d\n",
     110    cluster_dmsg("\n[DBG] %s : KHM initialized in cluster %x at cycle %d\n",
    111111                 __FUNCTION__ , local_cxy , hal_get_cycles() );
    112112
     
    114114        kcm_init( &cluster->kcm , KMEM_KCM );
    115115
    116     cluster_dmsg("\n[DMSG] %s : KCM initialized in cluster %x at cycle %d\n",
     116    cluster_dmsg("\n[DBG] %s : KCM initialized in cluster %x at cycle %d\n",
    117117                 __FUNCTION__ , local_cxy , hal_get_cycles() );
    118118
     
    125125        }
    126126
    127     cluster_dmsg("\n[DMSG] %s : cores initialized in cluster %x at cycle %d\n",
    128                  __FUNCTION__ , local_cxy , hal_get_cycles() );
     127cluster_dmsg("\n[DBG] %s : cores initialized in cluster %x at cycle %d\n",
     128__FUNCTION__ , local_cxy , hal_get_cycles() );
    129129
    130130    // initialises RPC fifo
    131         rpc_fifo_init( &cluster->rpc_fifo );
     131        local_fifo_init( &cluster->rpc_fifo );
    132132    cluster->rpc_threads = 0;
    133133
    134     cluster_dmsg("\n[DMSG] %s : RPC fifo inialized in cluster %x at cycle %d\n",
    135                  __FUNCTION__ , local_cxy , hal_get_cycles() );
     134cluster_dmsg("\n[DBG] %s : RPC fifo inialized in cluster %x at cycle %d\n",
     135__FUNCTION__ , local_cxy , hal_get_cycles() );
    136136
    137137    // initialise pref_tbl[] in process manager
     
    157157    }
    158158
    159     cluster_dmsg("\n[DMSG] %s Process Manager initialized in cluster %x at cycle %d\n",
    160                  __FUNCTION__ , local_cxy , hal_get_cycles() );
     159cluster_dmsg("\n[DBG] %s Process Manager initialized in cluster %x at cycle %d\n",
     160__FUNCTION__ , local_cxy , hal_get_cycles() );
    161161
    162162    hal_fence();
     
    184184//  Cores related functions
    185185////////////////////////////////////////////////////////////////////////////////////
    186 
    187 ////////////////////////////////
    188 void cluster_core_kernel_enter()
    189 {
    190     cluster_t * cluster = LOCAL_CLUSTER;
    191         hal_atomic_add( &cluster->cores_in_kernel , 1 );
    192 }
    193 
    194 ///////////////////////////////
    195 void cluster_core_kernel_exit()
    196 {
    197     cluster_t * cluster = LOCAL_CLUSTER;
    198         hal_atomic_add( &cluster->cores_in_kernel , -1 );
    199 }
    200186
    201187/////////////////////////////////
     
    353339void cluster_process_local_link( process_t * process )
    354340{
     341    uint32_t irq_state;
    355342    pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
    356343
    357344    // get lock protecting the process manager local list
    358     remote_spinlock_lock( XPTR( local_cxy , &pm->local_lock ) );
     345    remote_spinlock_lock_busy( XPTR( local_cxy , &pm->local_lock ) , & irq_state );
    359346
    360347    xlist_add_first( XPTR( local_cxy , &pm->local_root ),
     
    363350
    364351    // release lock protecting the process manager local list
    365     remote_spinlock_unlock( XPTR( local_cxy , &pm->local_lock ) );
     352    remote_spinlock_unlock_busy( XPTR( local_cxy , &pm->local_lock ) , irq_state );
    366353}
    367354
     
    369356void cluster_process_local_unlink( process_t * process )
    370357{
     358    uint32_t irq_state;
    371359    pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
    372360
    373361    // get lock protecting the process manager local list
    374     remote_spinlock_lock( XPTR( local_cxy , &pm->local_lock ) );
     362    remote_spinlock_lock_busy( XPTR( local_cxy , &pm->local_lock ) , &irq_state );
    375363
    376364    xlist_unlink( XPTR( local_cxy , &process->local_list ) );
     
    378366
    379367    // release lock protecting the process manager local list
    380     remote_spinlock_unlock( XPTR( local_cxy , &pm->local_lock ) );
     368    remote_spinlock_unlock_busy( XPTR( local_cxy , &pm->local_lock ) , irq_state );
    381369}
    382370
     
    384372void cluster_process_copies_link( process_t * process )
    385373{
     374    uint32_t irq_state;
    386375    pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
    387376
     
    401390
    402391    // get lock protecting copies_list[lpid]
    403     remote_spinlock_lock( copies_lock );
     392    remote_spinlock_lock_busy( copies_lock , &irq_state );
    404393
    405394    xlist_add_first( copies_root , copies_entry );
     
    407396
    408397    // release lock protecting copies_list[lpid]
    409     remote_spinlock_unlock( copies_lock );
     398    remote_spinlock_unlock_busy( copies_lock , irq_state );
    410399}
    411400
     
    413402void cluster_process_copies_unlink( process_t * process )
    414403{
     404    uint32_t irq_state;
    415405    pmgr_t * pm = &LOCAL_CLUSTER->pmgr;
    416406
     
    427417
    428418    // get lock protecting copies_list[lpid]
    429     remote_spinlock_lock( copies_lock );
     419    remote_spinlock_lock_busy( copies_lock , &irq_state );
    430420
    431421    xlist_unlink( copies_entry );
     
    433423
    434424    // release lock protecting copies_list[lpid]
    435     remote_spinlock_unlock( copies_lock );
     425    remote_spinlock_unlock_busy( copies_lock , irq_state );
    436426}
    437427
  • trunk/kernel/kern/cluster.h

    r279 r407  
    108108
    109109    // local parameters
    110         uint32_t          cores_nr;        /*! number of cores in cluster                     */
    111     uint32_t          cores_in_kernel; /*! number of cores currently in kernel mode       */
    112 
     110        uint32_t          cores_nr;        /*! actual number of cores in cluster              */
    113111    uint32_t          ram_size;        /*! physical memory size                           */
    114112    uint32_t          ram_base;        /*! physical memory base (local address)           */
     
    125123
    126124    // RPC
    127         rpc_fifo_t        rpc_fifo;        /*! RPC fifo                                       */
    128     uint32_t          rpc_threads;     /*! current number of RPC threads                  */
     125        remote_fifo_t     rpc_fifo;        /*! RPC fifo (one per cluster)                     */
     126    uint32_t          rpc_threads;     /*! current number of RPC threads in cluster       */
    129127
    130128    // DQDT
     
    173171
    174172/******************************************************************************************
    175  * This function checks the validity of a cluster identifier. TODO useful ??? [AG]
     173 * This function checks the validity of a cluster identifier.
    176174 ******************************************************************************************
    177175 * @ cxy    : cluster identifier to be checked.
     
    179177 *****************************************************************************************/
    180178bool_t cluster_is_undefined( cxy_t cxy );
    181 
    182 /******************************************************************************************
    183  * This function register sysfs information in cluster TODO ???  [AG]
    184  *****************************************************************************************/
    185 void cluster_sysfs_register();
    186179
    187180
  • trunk/kernel/kern/core.c

    r406 r407  
    107107        ticks = core->ticks_nr++;
    108108
    109         // handle pending alarms TODO ??? [AG]
    110         // alarm_clock( &core->alarm_mgr , ticks );
     109    // handle signals for all threads executing on this core
     110    sched_handle_signals( core );
    111111
    112112        // handle scheduler
    113         if( (ticks % CONFIG_SCHED_TICKS_PER_QUANTUM) == 0 ) sched_yield( NULL );
     113        if( (ticks % CONFIG_SCHED_TICKS_PER_QUANTUM) == 0 ) sched_yield();
    114114
    115115        // update DQDT
  • trunk/kernel/kern/do_syscall.c

    r406 r407  
    3131
    3232/////////////////////////////////////////////////////////////////////////////////////////////
     33// This ƒonction should never be called...
    3334/////////////////////////////////////////////////////////////////////////////////////////////
    34 static inline int sys_undefined()
     35static int sys_undefined()
    3536{
    3637    panic("undefined system call");
     
    4041/////////////////////////////////////////////////////////////////////////////////////////////
    4142// This array of pointers define the kernel functions implementing the syscalls.
    42 // It must be kept consistent with the enum in syscalls.h
     43// It must be kept consistent with the enum in "shared_syscalls.h" file.
    4344/////////////////////////////////////////////////////////////////////////////////////////////
    4445
     
    4849{
    4950    sys_thread_exit,        // 0
    50     sys_mmap,               // 1
     51    sys_thread_yield,       // 1
    5152    sys_thread_create,      // 2
    5253    sys_thread_join,        // 3
    5354    sys_thread_detach,      // 4
    54     sys_thread_yield,       // 5
     55    sys_undefined,          // 5
    5556    sys_sem,                // 6
    5657    sys_condvar,            // 7
    5758    sys_barrier,            // 8
    5859    sys_mutex,              // 9
    59     sys_thread_sleep,       // 10
    60     sys_thread_wakeup,      // 11
     60
     61    sys_undefined,          // 10
     62    sys_munmap,             // 11
    6163    sys_open,               // 12
    62     sys_creat,              // 13
     64    sys_mmap,               // 13
    6365    sys_read,               // 14
    6466    sys_write,              // 15
     
    6769    sys_unlink,             // 18
    6870    sys_pipe,               // 19
     71
    6972    sys_chdir,              // 20
    7073    sys_mkdir,              // 21
     
    7477    sys_closedir,           // 25
    7578    sys_getcwd,             // 26
    76     sys_clock,              // 27
     79    sys_undefined,          // 27 
    7780    sys_alarm,              // 28
    7881    sys_rmdir,              // 29
     82
    7983    sys_utls,               // 30
    8084    sys_chmod,              // 31
     
    8791    sys_stat,               // 38
    8892    sys_trace,              // 39
     93
     94    sys_get_config,         // 40
     95    sys_get_core,           // 41
     96    sys_get_cycle,          // 42
     97    sys_get_sched,          // 43
     98    sys_panic,              // 44
     99    sys_thread_sleep,       // 45
     100    sys_thread_wakeup,      // 46
    89101};
    90102
     
    102114        thread_user_time_update( this );
    103115
    104     // enable IRQs
     116    // enable interrupts
    105117        hal_enable_irq( NULL );
    106118 
     
    116128        }
    117129
    118         syscall_dmsg("\n[DMSG] %s : pid = %x / trdid = %x / service #%d\n"
    119                  "         arg0 = %x / arg1 = %x / arg2 = %x / arg3 = %x\n",
    120                          __FUNCTION__ , this->process->pid , this->trdid , service_num ,
    121                          arg0 , arg1 , arg2 , arg3 );
     130#if( CONFIG_SYSCALL_DEBUG & 0x1)
     131printk("\n[DBG] %s : pid = %x / trdid = %x / service #%d\n"
     132"      arg0 = %x / arg1 = %x / arg2 = %x / arg3 = %x\n",
     133__FUNCTION__ , this->process->pid , this->trdid , service_num , arg0 , arg1 , arg2 , arg3 );
     134#endif
    122135
    123136    // reset errno
     
    127140        error = syscall_tbl[service_num] ( arg0 , arg1 , arg2 , arg3 );
    128141
    129     // handle pending signals for the calling thread
    130     thread_signals_handle( this );
    131 
    132         // disable IRQs
     142    // disable interrupt
    133143        hal_disable_irq( NULL );
    134144
  • trunk/kernel/kern/do_syscall.h

    r16 r407  
    11/*
    2  * do_syscall.h - kernel service numbers asked by userland
     2 * do_syscall.h - generic syscall handler.
    33 *
    44 * Authors   Ghassan Almaless (2008,2009,2010,2011,2012)
     
    3232/********************************************************************************************
    3333 * This function calls the kernel function defined by the <service_num> argument.
     34 * The possible values for servic_num are defined in the syscalls/syscalls.h file.
    3435 ********************************************************************************************
    3536 * @ this        : pointer on calling thread descriptor
  • trunk/kernel/kern/kernel_init.c

    r406 r407  
    3232#include <barrier.h>
    3333#include <remote_barrier.h>
     34#include <remote_fifo.h>
    3435#include <core.h>
    3536#include <list.h>
     
    8586cluster_t            cluster_manager                         CONFIG_CACHE_LINE_ALIGNED;
    8687
    87 // This variable defines the TXT0 kernel terminal
     88// This variable defines the TXT0 kernel terminal (TX only)
    8889__attribute__((section(".kdata")))
    8990chdev_t              txt0_chdev                              CONFIG_CACHE_LINE_ALIGNED;
     
    121122vfs_ctx_t            fs_context[FS_TYPES_NR]                 CONFIG_CACHE_LINE_ALIGNED;
    122123
     124// These variables are used by the sched_yield function to save SR value
     125__attribute__((section(".kdata")))
     126uint32_t             switch_save_sr[CONFIG_MAX_LOCAL_CORES]  CONFIG_CACHE_LINE_ALIGNED;
     127
     128#if CONFIG_READ_DEBUG
     129uint32_t   enter_sys_read;
     130uint32_t   exit_sys_read;
     131
     132uint32_t   enter_devfs_move;
     133uint32_t   exit_devfs_move;
     134
     135uint32_t   enter_txt_read;
     136uint32_t   exit_txt_read;
     137
     138uint32_t   enter_chdev_cmd;
     139uint32_t   exit_chdev_cmd;
     140
     141uint32_t   enter_chdev_server;
     142uint32_t   exit_chdev_server;
     143
     144uint32_t   enter_tty_cmd;
     145uint32_t   exit_tty_cmd;
     146
     147uint32_t   enter_tty_isr;
     148uint32_t   exit_tty_isr;
     149#endif
    123150
    124151///////////////////////////////////////////////////////////////////////////////////////////
     
    137164           "    /_/        \\_\\ |______| |_|    |_|   \\_____/  |______/        |_|    |_|  |_|  \\_\\ |_|   |_|  \n"
    138165           "\n\n\t\t Advanced Locality Management Operating System / Multi Kernel Hybrid\n"
    139            "\n\n\t\t\t Version 0.0 / %d cluster(s) / %d core(s) per cluster\n\n", nclusters , ncores );
     166           "\n\n\t\t Version 0.0 / %d cluster(s) / %d core(s) per cluster / cycle %d\n\n",
     167           nclusters , ncores , hal_time_stamp() );
    140168}
    141169
     
    201229                {
    202230                    cxy_t  cxy = (x<<info->y_width) + y;
    203                     hal_remote_swd( XPTR( cxy , &chdev_dir.txt[0] ) ,
     231                    hal_remote_swd( XPTR( cxy , &chdev_dir.txt_tx[0] ) ,
    204232                                    XPTR( local_cxy , &txt0_chdev ) );
    205233                }
     
    273301            }
    274302
    275 #if( CONFIG_KINIT_DEBUG > 1 )
    276 printk("\n[DMSG] %s : created MMC in cluster %x / chdev = %x\n",
    277 __FUNCTION__ , channel , local_cxy , chdev_ptr );
     303#if( CONFIG_KINIT_DEBUG & 0x1 )
     304if( hal_time_stamp() > CONFIG_KINIT_DEBUG )
     305printk("\n[DBG] %s : created MMC in cluster %x / chdev = %x\n",
     306__FUNCTION__ , local_cxy , chdev_ptr );
    278307#endif
    279308        }
     
    301330                chdev_dir.dma[channel] = XPTR( local_cxy , chdev_ptr );
    302331
    303 #if( CONFIG_KINIT_DEBUG > 1 )
    304 printk("\n[DMSG] %s : created DMA[%d] in cluster %x / chdev = %x\n",
     332#if( CONFIG_KINIT_DEBUG & 0x1 )
     333if( hal_time_stamp() > CONFIG_KINIT_DEBUG )
     334printk("\n[DBG] %s : created DMA[%d] in cluster %x / chdev = %x\n",
    305335__FUNCTION__ , channel , local_cxy , chdev_ptr );
    306336#endif
     
    355385        impl     = IMPL_FROM_TYPE( dev_tbl[i].type );
    356386
    357         // There is one chdev per direction for NIC
    358         if (func == DEV_FUNC_NIC) directions = 2;
    359         else                      directions = 1;
     387        // There is one chdev per direction for NIC and for TXT
     388        if((func == DEV_FUNC_NIC) || (func == DEV_FUNC_TXT)) directions = 2;
     389        else                                                 directions = 1;
    360390
    361391        // The TXT0 chdev has already been created
     
    363393        else                      first_channel = 0;
    364394
    365         // do nothing for RO, that does not require a device descriptor.
     395        // do nothing for ROM, that does not require a device descriptor.
    366396        if( func == DEV_FUNC_ROM ) continue;
    367397
     
    394424
    395425                // allocate and initialize a local chdev
    396                 // if local cluster matches target cluster
     426                // when local cluster matches target cluster
    397427                if( target_cxy == local_cxy )
    398428                {
     
    420450                    if(func==DEV_FUNC_IOB             ) entry  = &chdev_dir.iob;
    421451                    if(func==DEV_FUNC_IOC             ) entry  = &chdev_dir.ioc[channel];
    422                     if(func==DEV_FUNC_TXT             ) entry  = &chdev_dir.txt[channel];
    423452                    if(func==DEV_FUNC_FBF             ) entry  = &chdev_dir.fbf[channel];
     453                    if((func==DEV_FUNC_TXT) && (rx==0)) entry  = &chdev_dir.txt_tx[channel];
     454                    if((func==DEV_FUNC_TXT) && (rx==1)) entry  = &chdev_dir.txt_rx[channel];
    424455                    if((func==DEV_FUNC_NIC) && (rx==0)) entry  = &chdev_dir.nic_tx[channel];
    425456                    if((func==DEV_FUNC_NIC) && (rx==1)) entry  = &chdev_dir.nic_rx[channel];
     
    435466                    }
    436467
    437 #if( CONFIG_KINIT_DEBUG > 1 )
    438 printk("\n[DMSG] %s : create chdev %s[%d] in cluster %x / chdev = %x\n",
    439 __FUNCTION__ , chdev_func_str( func ), channel , local_cxy , chdev );
     468#if( CONFIG_KINIT_DEBUG & 0x1 )
     469if( hal_time_stamp() > CONFIG_KINIT_DEBUG )
     470printk("\n[DBG] %s : create chdev %s / channel = %d / rx = %d / cluster %x / chdev = %x\n",
     471__FUNCTION__ , chdev_func_str( func ), channel , rx , local_cxy , chdev );
    440472#endif
    441473                }  // end if match
     
    451483///////////////////////////////////////////////////////////////////////////////////////////
    452484// This function is called by CP0 in cluster 0 to allocate memory and initialize the PIC
    453 // device, namely the informations attached to the external IOPIC controller.
     485// device, namely the informations attached to the external IOPIC controller, that
     486// must be replicated in all clusters (struct iopic_input).
    454487// This initialisation must be done before other devices initialisation because the IRQ
    455 // routing infrastructure is required for internal and external devices initialisation.
     488// routing infrastructure is required for both internal and external devices init.
    456489///////////////////////////////////////////////////////////////////////////////////////////
    457490// @ info    : pointer on the local boot-info structure.
     
    490523    assert( found , __FUNCTION__ , "PIC device not found\n" );
    491524
    492     // allocate and initialize the PIC chdev in local cluster
    493     chdev = chdev_create( func,
     525    // allocate and initialize the PIC chdev in cluster 0
     526    chdev = chdev_create( DEV_FUNC_PIC,
    494527                          impl,
    495528                          0,      // channel
     
    502535    dev_pic_init( chdev );
    503536
    504     // register extended pointer on PIC chdev in "chdev_dir" array in all clusters
     537    // register, in all clusters, the extended pointer
     538    // on PIC chdev in "chdev_dir" array
    505539    xptr_t * entry = &chdev_dir.pic;   
    506540               
     
    515549    }
    516550
    517     // initialize the "iopic_input" structure
     551    // initialize, in all clusters, the "iopic_input" structure
    518552    // defining how external IRQs are connected to IOPIC
    519     uint32_t   id;
    520     uint8_t    valid;
    521     uint32_t   type;
    522     uint8_t    channel;
    523     uint8_t    is_rx;
     553
     554    // register default value for unused inputs
     555    for( x = 0 ; x < info->x_size ; x++ )
     556    {
     557        for( y = 0 ; y < info->y_size ; y++ )
     558        {
     559            cxy_t  cxy = (x<<info->y_width) + y;
     560            hal_remote_memset( XPTR( cxy , &iopic_input ) , 0xFF , sizeof(iopic_input_t) );
     561        }
     562    }
     563
     564    // register input IRQ index for valid inputs
     565    uint32_t   id;         // input IRQ index
     566    uint8_t    valid;      // input IRQ is connected
     567    uint32_t   type;       // source device type
     568    uint8_t    channel;    // source device channel
     569    uint8_t    is_rx;      // source device direction
     570    uint32_t * ptr;        // local pointer on one field in iopic_input stucture
    524571
    525572    for( id = 0 ; id < CONFIG_MAX_EXTERNAL_IRQS ; id++ )
     
    529576        channel = dev_tbl[i].irq[id].channel;
    530577        is_rx   = dev_tbl[i].irq[id].is_rx;
    531 
    532         if( valid )  // only valid inputs are registered
    533         {
    534             uint32_t * index;  // local pointer on one entry
    535             uint16_t func = FUNC_FROM_TYPE( type );
    536 
    537             if     ( func == DEV_FUNC_TXT )
    538             index = &iopic_input.txt[channel];
    539             else if( func == DEV_FUNC_IOC )
    540             index = &iopic_input.ioc[channel];
    541             else if( (func == DEV_FUNC_NIC) && (is_rx == 0) )
    542             index = &iopic_input.nic_tx[channel];
    543             else if( (func == DEV_FUNC_NIC) && (is_rx != 0) )
    544             index = &iopic_input.nic_rx[channel];
    545             else if( func == DEV_FUNC_IOB )
    546             index = &iopic_input.iob;
    547             else
    548             assert( false , __FUNCTION__ , "illegal source device for IOPIC input" );
    549 
    550             // set entry in local structure
    551             *index = id;
     578        func    = FUNC_FROM_TYPE( type );
     579
     580        // get pointer on relevant field in iopic_input
     581        if( valid )
     582        {
     583            if     ( func == DEV_FUNC_IOC )                 ptr = &iopic_input.ioc[channel];
     584            else if((func == DEV_FUNC_TXT) && (is_rx == 0)) ptr = &iopic_input.txt_tx[channel];
     585            else if((func == DEV_FUNC_TXT) && (is_rx != 0)) ptr = &iopic_input.txt_rx[channel];
     586            else if((func == DEV_FUNC_NIC) && (is_rx == 0)) ptr = &iopic_input.nic_tx[channel];
     587            else if((func == DEV_FUNC_NIC) && (is_rx != 0)) ptr = &iopic_input.nic_rx[channel];
     588            else if( func == DEV_FUNC_IOB )                 ptr = &iopic_input.iob;
     589            else     panic( "illegal source device for IOPIC input" );
     590
     591            // set one entry in all "iopic_input" structures
     592            for( x = 0 ; x < info->x_size ; x++ )
     593            {
     594                for( y = 0 ; y < info->y_size ; y++ )
     595                {
     596                    cxy_t  cxy = (x<<info->y_width) + y;
     597                    hal_remote_swd( XPTR( cxy , ptr ) , id );
     598                }
     599            }
    552600        }
    553601    }
    554602
    555 #if( CONFIG_KINIT_DEBUG > 1 )
    556 printk("\n[DMSG] %s created PIC chdev in cluster %x at cycle %d\n",
    557 __FUNCTION__ , local_cxy , (uint32_t)hal_time_stamp() );
     603#if( CONFIG_KINIT_DEBUG & 0x1 )
     604if( hal_time_stamp() > CONFIG_KINIT_DEBUG )
     605{
     606    printk("\n[DBG] %s created PIC chdev in cluster %x at cycle %d\n",
     607    __FUNCTION__ , local_cxy , (uint32_t)hal_time_stamp() );
     608    dev_pic_inputs_display();
     609}
    558610#endif
    559611   
     
    715767    hal_set_current_thread( thread );
    716768
    717     // each core initializes the idle thread "locks_root" and "xlocks_root" fields
     769    // each core register core descriptor pointer in idle thread descriptor
     770    thread->core = &LOCAL_CLUSTER->core_tbl[core_lid];
     771
     772    // each core initializes locks_root" and "xlocks_root" in idle thread descriptor
    718773    list_root_init( &thread->locks_root );
    719774    xlist_root_init( XPTR( local_cxy , &thread->xlocks_root ) );
     
    728783
    729784    if( (core_lid ==  0) && (local_cxy == 0) )
    730     printk("\n[KINIT] %s : exit barrier 0 : TXT0 initialized / cycle %d\n",
     785    kinit_dmsg("\n[DBG] %s : exit barrier 0 : TXT0 initialized / cycle %d\n",
    731786    __FUNCTION__, hal_time_stamp() );
    732787
    733788    /////////////////////////////////////////////////////////////////////////////
    734     // STEP 1 : all cores check its core identifier.
     789    // STEP 1 : all cores check core identifier.
    735790    //          CP0 initializes the local cluster manager.
    736791    //          This includes the memory allocators.
     
    762817
    763818    if( (core_lid ==  0) && (local_cxy == 0) )
    764     printk("\n[KINIT] %s : exit barrier 1 : clusters initialised / cycle %d\n",
     819    kinit_dmsg("\n[DBG] %s : exit barrier 1 : clusters initialised / cycle %d\n",
    765820    __FUNCTION__, hal_time_stamp() );
    766821
    767822    /////////////////////////////////////////////////////////////////////////////////
    768     // STEP 2 : all CP0s initialize the process_zero descriptor.
     823    // STEP 2 : CP0 initializes the process_zero descriptor.
    769824    //          CP0 in cluster 0 initializes the IOPIC device.
    770825    /////////////////////////////////////////////////////////////////////////////////
     
    787842
    788843    if( (core_lid ==  0) && (local_cxy == 0) )
    789     printk("\n[KINIT] %s : exit barrier 2 : PIC initialised / cycle %d\n",
     844    kinit_dmsg("\n[DBG] %s : exit barrier 2 : PIC initialised / cycle %d\n",
    790845    __FUNCTION__, hal_time_stamp() );
    791846
    792847    ////////////////////////////////////////////////////////////////////////////////
    793     // STEP 3 : all CP0s initialize the distibuted LAPIC descriptor.
    794     //          all CP0s initialize the internal chdev descriptors
    795     //          all CP0s initialize the local external chdev descriptors
     848    // STEP 3 : CP0 initializes the distibuted LAPIC descriptor.
     849    //          CP0 initializes the internal chdev descriptors
     850    //          CP0 initialize the local external chdev descriptors
    796851    ////////////////////////////////////////////////////////////////////////////////
    797852
     
    818873
    819874    if( (core_lid ==  0) && (local_cxy == 0) )
    820     printk("\n[KINIT] %s : exit barrier 3 : all chdev initialised / cycle %d\n",
     875    kinit_dmsg("\n[DBG] %s : exit barrier 3 : all chdev initialised / cycle %d\n",
    821876               __FUNCTION__, hal_time_stamp());
    822877
    823878    /////////////////////////////////////////////////////////////////////////////////
    824879    // STEP 4 : All cores enable IPI (Inter Procesor Interrupt),
    825     //          All cores initialise specific core registers
    826880    //          Alh cores initialize IDLE thread.
    827881    //          Only CP0 in cluster 0 creates the VFS root inode.
     
    837891    hal_enable_irq( &status );
    838892
    839     // All cores initialize specific core registers
    840     hal_core_init( info );
    841 
    842893    // all cores initialize the idle thread descriptor
    843894    error = thread_kernel_init( thread,
     
    857908
    858909#if CONFIG_KINIT_DEBUG
    859 sched_display();
     910sched_display( core_lid );
    860911#endif
    861912
     
    928979
    929980    if( (core_lid ==  0) && (local_cxy == 0) )
    930     printk("\n[KINIT] %s : exit barrier 4 : VFS_root = %l in cluster 0 / cycle %d\n",
     981    kinit_dmsg("\n[DBG] %s : exit barrier 4 : VFS_root = %l in cluster 0 / cycle %d\n",
    931982               __FUNCTION__, vfs_root_inode_xp , hal_time_stamp());
    932983
     
    9871038
    9881039    if( (core_lid ==  0) && (local_cxy == 0) )
    989     printk("\n[KINIT] %s : exit barrier 5 : VFS_root = %l in cluster IO / cycle %d\n",
     1040    kinit_dmsg("\n[DBG] %s : exit barrier 5 : VFS_root = %l in cluster IO / cycle %d\n",
    9901041    __FUNCTION__, vfs_root_inode_xp , hal_time_stamp() );
    9911042
     
    10201071
    10211072    if( (core_lid ==  0) && (local_cxy == 0) )
    1022     printk("\n[KINIT] %s : exit barrier 6 : dev_root = %l in cluster IO / cycle %d\n",
     1073    kinit_dmsg("\n[DBG] %s : exit barrier 6 : dev_root = %l in cluster IO / cycle %d\n",
    10231074    __FUNCTION__, devfs_dev_inode_xp , hal_time_stamp() );
    10241075
     
    10571108
    10581109    if( (core_lid ==  0) && (local_cxy == 0) )
    1059     printk("\n[KINIT] %s : exit barrier 7 : dev_root = %l in cluster 0 / cycle %d\n",
     1110    kinit_dmsg("\n[DBG] %s : exit barrier 7 : dev_root = %l in cluster 0 / cycle %d\n",
    10601111    __FUNCTION__, devfs_dev_inode_xp , hal_time_stamp() );
    10611112
     
    10751126    /////////////////////////////////////////////////////////////////////////////////
    10761127
     1128#if CONFIG_KINIT_DEBUG
     1129sched_display( core_lid );
     1130#endif
     1131
    10771132    if( (core_lid ==  0) && (local_cxy == 0) )
    1078     printk("\n[KINIT] %s : exit barrier 8 : process init created / cycle %d\n",
     1133    kinit_dmsg("\n[DBG] %s : exit barrier 8 : process init created / cycle %d\n",
    10791134    __FUNCTION__ , hal_time_stamp() );
    10801135
     
    11181173                   sizeof( core_t            ),
    11191174                   sizeof( scheduler_t       ),
    1120                    sizeof( rpc_fifo_t        ),
     1175                   sizeof( remote_fifo_t     ),
    11211176                   sizeof( page_t            ),
    11221177                   sizeof( mapper_t          ),
     
    11391194    dev_pic_enable_timer( CONFIG_SCHED_TICK_MS_PERIOD );
    11401195
    1141     // each core jump to idle thread
     1196    // each core jump to thread_idle_func
    11421197    thread_idle_func();
    11431198}
  • trunk/kernel/kern/printk.c

    r406 r407  
    190190        goto xprintf_text;
    191191    }
    192 } // end xprintf()
    193 
    194 ///////////////////////////////////////////////////////////////////////////////////
    195 // This static function is called by kernel_printf() to display a string on the
    196 // TXT channel defined by the <channel> argument.
    197 // The access mode is defined by the <busy> argument:
    198 // - if <busy> is true, it uses the dev_txt_sync_write() function, that takes the
    199 //   TXT lock, and call directly the relevant TXT driver, without descheduling.
    200 // - if <busy is false, it uses the dev_txt_write() function, that register the
    201 //   write buffer in the relevant TXT chdev queue, and uses a descheduling policy.
    202 ///////////////////////////////////////////////////////////////////////////////////
    203 // @ channel  : TXT channel.
    204 // @ busy     : TXT device acces mode (busy waiting if non zero).
    205 // @ buf      : buffer containing the characters.
    206 // @ nc       : number of characters.
    207 // return 0 if success / return -1 if TTY0 busy after 10000 retries.
    208 ///////////////////////////////////////////////////////////////////////////////////
    209 static error_t txt_write( uint32_t  channel,
    210                           uint32_t  busy,
    211                           char    * buffer,
    212                           uint32_t  count )
    213 {
    214     if( busy ) return dev_txt_sync_write( channel , buffer , count );
    215     else       return dev_txt_write( channel , buffer , count );
    216 
     192} // end snprintf()
    217193
    218194//////////////////////////////////////////////////////////////////////////////////////
    219 // This static function is called by printk(), assert() and nolock_printk() to build
    220 // a formated string.
     195// This static function is called by printk(), assert() and nolock_printk()
     196// to display a formated string on TXT0, using a busy waiting policy.
    221197//////////////////////////////////////////////////////////////////////////////////////
    222 // @ channel   : channel index.
    223 // @ busy      : TXT device access mode (busy waiting if non zero).
    224198// @ format    : printf like format.
    225 // @ args      : format arguments.
     199// @ args      : va_list of arguments.
    226200//////////////////////////////////////////////////////////////////////////////////////
    227 static void kernel_printf( uint32_t   channel,
    228                            uint32_t   busy,
    229                            char     * format,
     201static void kernel_printf( char     * format,
    230202                           va_list  * args )
    231203{
     
    239211        if (i)
    240212        {
    241             txt_write( channel, busy, format, i );
     213            dev_txt_sync_write( format, i );
    242214            format += i;
    243215        }
     
    276248                {
    277249                    val = -val;
    278                     txt_write( channel, busy, "-" , 1 );
     250                    dev_txt_sync_write( "-" , 1 );
    279251                }
    280252                for(i = 0; i < 10; i++)
     
    302274            {
    303275                uint32_t val = va_arg( *args , uint32_t );
    304                 txt_write( channel, busy, "0x" , 2 );
     276                dev_txt_sync_write( "0x" , 2 );
    305277                for(i = 0; i < 8; i++)
    306278                {
     
    315287            {
    316288                uint32_t val = va_arg( *args , uint32_t );
    317                 txt_write( channel, busy, "0x" , 2 );
     289                dev_txt_sync_write( "0x" , 2 );
    318290                for(i = 0; i < 8; i++)
    319291                {
     
    328300            {
    329301                unsigned long long val = va_arg( *args , unsigned long long );
    330                 txt_write( channel, busy, "0x" , 2 );
     302                dev_txt_sync_write( "0x" , 2 );
    331303                for(i = 0; i < 16; i++)
    332304                {
     
    341313            {
    342314                unsigned long long val = va_arg( *args , unsigned long long );
    343                 txt_write( channel, busy, "0x" , 2 );
     315                dev_txt_sync_write( "0x" , 2 );
    344316                for(i = 0; i < 16; i++)
    345317                {
     
    363335            default:
    364336            {
    365                 txt_write( channel , busy,
    366                            "\n[PANIC] in kernel_printf() : illegal format\n", 45 );
    367             }
    368         }
    369 
    370         if( pbuf != NULL ) txt_write( channel, busy, pbuf, len );
     337                dev_txt_sync_write( "\n[PANIC] in kernel_printf() : illegal format\n", 45 );
     338            }
     339        }
     340
     341        if( pbuf != NULL ) dev_txt_sync_write( pbuf, len );
    371342       
    372343        goto printf_text;
     
    382353
    383354    // get pointers on TXT0 chdev
    384     xptr_t    txt0_xp  = chdev_dir.txt[0];
     355    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
    385356    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
    386357    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     
    394365    // call kernel_printf on TXT0, in busy waiting mode
    395366    va_start( args , format );
    396     kernel_printf( 0 , 1 , format , &args );
     367    kernel_printf( format , &args );
    397368    va_end( args );
    398369
     
    408379    // call kernel_printf on TXT0, in busy waiting mode
    409380    va_start( args , format );
    410     kernel_printf( 0 , 1 , format , &args );
     381    kernel_printf( format , &args );
    411382    va_end( args );
    412383}
     
    419390
    420391    // get pointers on TXT0 chdev
    421     xptr_t    txt0_xp  = chdev_dir.txt[0];
     392    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
    422393    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
    423394    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     
    431402    // call kernel_printf on TXT0, in busy waiting mode
    432403    va_start( args , format );
    433     kernel_printf( 0 , 1 , format , &args );
     404    kernel_printf( format , &args );
    434405    va_end( args );
    435406
     
    456427    {
    457428        // get pointers on TXT0 chdev
    458         xptr_t    txt0_xp  = chdev_dir.txt[0];
     429        xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
    459430        cxy_t     txt0_cxy = GET_CXY( txt0_xp );
    460431        chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     
    471442        // call kernel_printf on TXT0, in busy waiting to print format
    472443        va_start( args , format );
    473         kernel_printf( 0 , 1 , format , &args );
     444        kernel_printf( format , &args );
    474445        va_end( args );
    475446
  • trunk/kernel/kern/printk.h

    r406 r407  
    102102             char       * format , ... );
    103103
    104 #define panic(fmt, ...)     _panic("[PANIC] %s(): " fmt "\n", __func__, ##__VA_ARGS__)
     104#define panic(fmt, ...)     _panic("\n[PANIC] %s(): " fmt "\n", __func__, ##__VA_ARGS__)
    105105
    106106///////////////////////////////////////////////////////////////////////////////////
     
    108108///////////////////////////////////////////////////////////////////////////////////
    109109
     110#if CONFIG_CHDEV_DEBUG
     111#define chdev_dmsg(...)   if(hal_time_stamp() > CONFIG_CHDEV_DEBUG) printk(__VA_ARGS__)
     112#else
     113#define chdev_dmsg(...)
     114#endif
     115
    110116#if CONFIG_CLUSTER_DEBUG
    111117#define cluster_dmsg(...)   if(hal_time_stamp() > CONFIG_CLUSTER_DEBUG) printk(__VA_ARGS__)
     
    186192#endif
    187193
     194#if CONFIG_GRPC_DEBUG
     195#define grpc_dmsg(...)   if(hal_time_stamp() > CONFIG_GRPC_DEBUG) printk(__VA_ARGS__)
     196#else
     197#define grpc_dmsg(...)
     198#endif
     199
    188200#if CONFIG_IDLE_DEBUG
    189201#define idle_dmsg(...)   if(hal_time_stamp() > CONFIG_IDLE_DEBUG) printk(__VA_ARGS__)
     
    234246#endif
    235247
     248#if CONFIG_MMAP_DEBUG
     249#define mmap_dmsg(...)   if(hal_time_stamp() > CONFIG_MMAP_DEBUG) printk(__VA_ARGS__)
     250#else
     251#define mmap_dmsg(...)
     252#endif
     253
    236254#if CONFIG_MMC_DEBUG
    237255#define mmc_dmsg(...)   if(hal_time_stamp() > CONFIG_MMC_DEBUG) printk(__VA_ARGS__)
     
    264282#endif
    265283
     284#if CONFIG_READ_DEBUG
     285#define read_dmsg(...)   if(hal_time_stamp() > CONFIG_READ_DEBUG) printk(__VA_ARGS__)
     286#else
     287#define read_dmsg(...)
     288#endif
     289
    266290#if CONFIG_RPC_DEBUG
    267291#define rpc_dmsg(...)   if(hal_time_stamp() > CONFIG_RPC_DEBUG) printk(__VA_ARGS__)
     
    310334#else
    311335#define vmm_dmsg(...)
     336#endif
     337
     338#if CONFIG_WRITE_DEBUG
     339#define write_dmsg(...)   if(hal_time_stamp() > CONFIG_WRITE_DEBUG) printk(__VA_ARGS__)
     340#else
     341#define write_dmsg(...)
    312342#endif
    313343
  • trunk/kernel/kern/process.c

    r406 r407  
    3939#include <thread.h>
    4040#include <list.h>
     41#include <string.h>
    4142#include <scheduler.h>
    4243#include <remote_spinlock.h>
     
    9091    pid_t       parent_pid;
    9192
    92     process_dmsg("\n[DMSG] %s : core[%x,%d] enters for process %x\n",
    93     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid );
     93        error_t     error1;
     94        error_t     error2;
     95        error_t     error3;
     96    xptr_t      stdin_xp;
     97    xptr_t      stdout_xp;
     98    xptr_t      stderr_xp;
     99    uint32_t    stdin_id;
     100    uint32_t    stdout_id;
     101    uint32_t    stderr_id;
     102
     103process_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x\n",
     104__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid );
    94105
    95106    // get parent process cluster, local pointer, and pid
    96     // for all processes other than process_zero
    97     if( process == &process_zero )
     107    // for all processes other than kernel process
     108    if( process == &process_zero )                   // kernel process
    98109    {
    99110        assert( (pid == 0) , __FUNCTION__ , "process_zero must have PID = 0\n");
     
    101112        parent_cxy = 0;
    102113        parent_ptr = NULL;
    103         parent_pid = 0;      // process_zero is its own parent...
    104     }
    105     else
    106     {
    107         assert( (parent_xp != XPTR_NULL) , __FUNCTION__ , "parent_xp cannot be NULL\n");
    108 
     114        parent_pid = 0;     
     115    }
     116    else                                             // user process
     117    {
    109118        parent_cxy = GET_CXY( parent_xp );
    110119        parent_ptr = (process_t *)GET_PTR( parent_xp );
     
    112121    }
    113122
    114     // initialize PID and PPID
    115         process->pid   = pid;
    116     process->ppid  = parent_pid;
    117 
    118     // initialize reference process vmm (not for kernel process)
    119     if( pid ) vmm_init( process );
    120 
    121     // reset reference process file descriptors array
    122         process_fd_init( process );
    123 
    124     // reset reference process files structures and cwd_lock
    125         process->vfs_root_xp     = XPTR_NULL;
    126         process->vfs_bin_xp      = XPTR_NULL;
    127         process->vfs_cwd_xp      = XPTR_NULL;
    128     remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ) );
    129 
    130     // reset children list root
    131     xlist_root_init( XPTR( local_cxy , &process->children_root ) );
    132         process->children_nr     = 0;
    133 
    134     // reset semaphore / mutex / barrier / condvar list roots
    135     xlist_root_init( XPTR( local_cxy , &process->sem_root ) );
    136     xlist_root_init( XPTR( local_cxy , &process->mutex_root ) );
    137     xlist_root_init( XPTR( local_cxy , &process->barrier_root ) );
    138     xlist_root_init( XPTR( local_cxy , &process->condvar_root ) );
    139     remote_spinlock_init( XPTR( local_cxy , &process->sync_lock ) );
    140 
    141     // register new process in the parent children list (not for kernel process)
     123    // initialize PID, PPID, and REF
     124        process->pid    = pid;
     125    process->ppid   = parent_pid;
     126    process->ref_xp = XPTR( local_cxy , process );
     127
     128    // initialize vmm, fd array and others structures for user processes.
     129    // These structures are not used by the kernel process.
    142130    if( pid )
    143131    {
     132        // initialize vmm (not for kernel)
     133        vmm_init( process );
     134
     135process_dmsg("\n[DBG] %s : core[%x,%d] / vmm initialised for process %x\n",
     136__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid );
     137
     138        // initialize fd_array (not for kernel)
     139        process_fd_init( process );
     140
     141        // create stdin / stdout / stderr pseudo-files (not for kernel)
     142        if( parent_pid == 0 )                                              // process_init
     143        {
     144            error1 = vfs_open( process,
     145                               CONFIG_INIT_STDIN,
     146                               O_RDONLY,
     147                               0,                // FIXME chmod
     148                               &stdin_xp,
     149                               &stdin_id );
     150
     151            error2 = vfs_open( process,
     152                               CONFIG_INIT_STDOUT,
     153                               O_WRONLY,
     154                               0,                // FIXME chmod
     155                               &stdout_xp,
     156                               &stdout_id );
     157
     158            error3 = vfs_open( process,
     159                               CONFIG_INIT_STDERR,
     160                               O_WRONLY,
     161                               0,                // FIXME chmod
     162                               &stderr_xp,
     163                               &stderr_id );
     164        }
     165        else                                                               // user process
     166        {
     167            error1 = vfs_open( process,
     168                               CONFIG_USER_STDIN,
     169                               O_RDONLY,
     170                               0,                // FIXME chmod
     171                               &stdin_xp,
     172                               &stdin_id );
     173
     174            error2 = vfs_open( process,
     175                               CONFIG_USER_STDOUT,
     176                               O_WRONLY,
     177                               0,                // FIXME chmod
     178                               &stdout_xp,
     179                               &stdout_id );
     180
     181            error3 = vfs_open( process,
     182                               CONFIG_USER_STDERR,
     183                               O_WRONLY,
     184                               0,                // FIXME chmod
     185                               &stderr_xp,
     186                               &stderr_id );
     187        }
     188
     189        assert( ((error1 == 0) && (error2 == 0) && (error3 == 0)) , __FUNCTION__ ,
     190        "cannot open stdin/stdout/stderr pseudo files\n");
     191
     192        assert( ((stdin_id == 0) && (stdout_id == 1) && (stderr_id == 2)) , __FUNCTION__ ,
     193        "bad indexes : stdin %d / stdout %d / stderr %d \n", stdin_id , stdout_id , stderr_id );
     194
     195process_dmsg("\n[DBG] %s : core[%x,%d] / fd array initialised for process %x\n",
     196__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid );
     197
     198
     199        // reset reference process files structures and cwd_lock (not for kernel)
     200            process->vfs_root_xp     = XPTR_NULL;
     201            process->vfs_bin_xp      = XPTR_NULL;
     202            process->vfs_cwd_xp      = XPTR_NULL;
     203        remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ) );
     204
     205        // reset children list root (not for kernel)
     206        xlist_root_init( XPTR( local_cxy , &process->children_root ) );
     207            process->children_nr     = 0;
     208
     209        // reset semaphore / mutex / barrier / condvar list roots (nor for kernel)
     210        xlist_root_init( XPTR( local_cxy , &process->sem_root ) );
     211        xlist_root_init( XPTR( local_cxy , &process->mutex_root ) );
     212        xlist_root_init( XPTR( local_cxy , &process->barrier_root ) );
     213        xlist_root_init( XPTR( local_cxy , &process->condvar_root ) );
     214        remote_spinlock_init( XPTR( local_cxy , &process->sync_lock ) );
     215
     216        // register new process in the parent children list (nor for kernel)
    144217        xptr_t entry = XPTR( local_cxy  , &process->brothers_list );
    145218        xptr_t root  = XPTR( parent_cxy , &parent_ptr->children_root );
     
    156229    spinlock_init( &process->th_lock );
    157230
    158     // set ref_xp field
    159     process->ref_xp = XPTR( local_cxy , process );
    160 
    161231    // register new process descriptor in local cluster manager local_list
    162232    cluster_process_local_link( process );
     
    169239        hal_fence();
    170240
    171     process_dmsg("\n[DMSG] %s : exit for process %x in cluster %x\n",
    172                  __FUNCTION__ , pid );
     241process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x\n",
     242__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid );
    173243
    174244}  // process_reference init()
     
    181251    cxy_t       ref_cxy = GET_CXY( reference_process_xp );
    182252    process_t * ref_ptr = (process_t *)GET_PTR( reference_process_xp );
     253
     254    // set the pid, ppid, ref_xp fields in local process
     255    local_process->pid    = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->pid ) );
     256    local_process->ppid   = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->ppid ) );
     257    local_process->ref_xp = reference_process_xp;
     258
     259process_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x in cluster %x\n",
     260__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , local_process->pid );
    183261
    184262    // reset local process vmm
     
    192270    local_process->vfs_bin_xp  = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_bin_xp ) );
    193271    local_process->vfs_cwd_xp  = XPTR_NULL;
    194 
    195     // set the pid, ppid, ref_xp fields
    196     local_process->pid    = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->pid ) );
    197     local_process->ppid   = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->ppid ) );
    198     local_process->ref_xp = reference_process_xp;
    199 
    200     process_dmsg("\n[DMSG] %s : enter for process %x in cluster %x\n",
    201                  __FUNCTION__ , local_process->pid );
    202272
    203273    // reset children list root (not used in a process descriptor copy)
     
    233303        hal_fence();
    234304
    235     process_dmsg("\n[DMSG] %s : exit for process %x in cluster %x\n",
    236                  __FUNCTION__ , local_process->pid );
     305process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x in cluster %x\n",
     306__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , local_process->pid );
    237307
    238308    return 0;
     
    288358    vmm_destroy( process );
    289359
    290         process_dmsg("\n[DMSG] %s for pid %d / page_faults = %d\n",
     360        process_dmsg("\n[DBG] %s for pid %d / page_faults = %d\n",
    291361                 __FUNCTION__ , process->pid, process->vmm.pgfault_nr );
    292 }
     362
     363}  // end process_destroy()
    293364
    294365////////////////////////////////////////
     
    298369    uint32_t       ltid;      // index in process th_tbl
    299370    uint32_t       count;     // thread counter
     371
     372printk("\n@@@ %s enter\n", __FUNCTION__ );
    300373
    301374    // get lock protecting th_tbl[]
     
    317390    }
    318391
    319     volatile uint32_t ko;
     392printk("\n@@@ %s : %d signal(s) sent\n", __FUNCTION__, count );
    320393
    321394    // second loop on threads to wait acknowledge from scheduler,
     
    329402        if( thread != NULL )
    330403        {
    331             // wait scheduler acknowledge
    332             do { ko = (thread->signals & THREAD_SIG_KILL); } while( ko );
    333 
    334             // unlink thread from brothers list if required
    335             if( (thread->flags & THREAD_FLAG_DETACHED) == 0 )
    336             xlist_unlink( XPTR( local_cxy , &thread->brothers_list ) );
     404
     405printk("\n@@@ %s start polling at cycle %d\n", __FUNCTION__ , hal_time_stamp() );
     406
     407            // poll the THREAD_SIG_KILL bit until reset
     408            while( thread->signals & THREAD_SIG_KILL ) asm volatile( "nop" );
     409
     410printk("\n@@@ %s exit polling\n", __FUNCTION__ );
     411
     412            // detach target thread from parent if attached
     413            if( (thread->flags & THREAD_FLAG_DETACHED) != 0 )
     414            thread_child_parent_unlink( thread->parent , XPTR( local_cxy , thread ) );
    337415
    338416            // unlink thread from process
     
    346424    }
    347425
     426printk("\n@@@ %s : %d ack(s) received\n", __FUNCTION__, count );
     427
    348428    // release lock protecting th_tbl[]
    349429    spinlock_unlock( &process->th_lock );
     
    351431    // release memory allocated for process descriptor
    352432    process_destroy( process );
    353 }
     433
     434printk("\n[@@@] %s : core[%x,%d] exit\n",
     435__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid );
     436
     437}  // end process_kill()
    354438
    355439///////////////////////////////////////////////
     
    440524
    441525/////////////////////////////////////////////////
    442 error_t process_fd_register(  xptr_t     file_xp,
    443                               uint32_t * file_id )
     526error_t process_fd_register( process_t * process,
     527                             xptr_t      file_xp,
     528                             uint32_t  * fdid )
    444529{
    445530    bool_t    found;
     
    447532    xptr_t    xp;
    448533
    449     // get extended pointer on reference process
    450     xptr_t ref_xp = CURRENT_THREAD->process->ref_xp;
    451 
    452534    // get reference process cluster and local pointer
     535    xptr_t ref_xp = process->ref_xp;
    453536    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
    454537    cxy_t       ref_cxy = GET_CXY( ref_xp );
     
    467550            hal_remote_swd( XPTR( ref_cxy , &ref_ptr->fd_array.array[id] ) , file_xp );
    468551                hal_remote_atomic_add( XPTR( ref_cxy , &ref_ptr->fd_array.current ) , 1 );
    469                         *file_id = id;
     552                        *fdid = id;
    470553            break;
    471554        }
     
    481564////////////////////////////////////////////////
    482565xptr_t process_fd_get_xptr( process_t * process,
    483                             uint32_t    file_id )
     566                            uint32_t    fdid )
    484567{
    485568    xptr_t  file_xp;
    486569
    487570    // access local copy of process descriptor
    488     file_xp = process->fd_array.array[file_id];
     571    file_xp = process->fd_array.array[fdid];
    489572
    490573    if( file_xp == XPTR_NULL )
     
    496579
    497580        // access reference process descriptor
    498         file_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->fd_array.array[file_id] ) );
     581        file_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->fd_array.array[fdid] ) );
    499582
    500583        // update local fd_array if found
    501584        if( file_xp != XPTR_NULL )
    502585        {
    503             process->fd_array.array[file_id] = file_xp;
     586            process->fd_array.array[fdid] = file_xp;
    504587        }
    505588    }
    506589
    507590    return file_xp;
    508 }
     591
     592}  // end process_fd_get_xptr()
    509593
    510594///////////////////////////////////////////
     
    543627    // release lock on source process fd_array
    544628        remote_spinlock_unlock( XPTR( src_cxy , &src_ptr->lock ) );
    545 }
     629
     630}  // end process_fd_remote_copy()
    546631
    547632////////////////////////////////////////////////////////////////////////////////////
     
    561646    assert( (thread != NULL) , __FUNCTION__ , "thread argument is NULL" );
    562647
    563     // search a free slot in th_tbl[]
     648    // search a free slot in th_tbl[]
     649    // 0 is not a valid ltid value
    564650    found = false;
    565     for( ltid = 0 ; ltid < CONFIG_THREAD_MAX_PER_CLUSTER ; ltid++ )
     651    for( ltid = 1 ; ltid < CONFIG_THREAD_MAX_PER_CLUSTER ; ltid++ )
    566652    {
    567653        if( process->th_tbl[ltid] == NULL )
     
    606692{
    607693    char           * path;                            // pathname to .elf file
     694    bool_t           keep_pid;                        // new process keep parent PID if true
    608695    process_t      * process;                         // local pointer on new process
    609696    pid_t            pid;                             // new process pid
    610697    xptr_t           parent_xp;                       // extended pointer on parent process
    611     cxy_t            parent_cxy;
    612     process_t      * parent_ptr;
    613     uint32_t         parent_pid;
     698    cxy_t            parent_cxy;                      // parent process local cluster
     699    process_t      * parent_ptr;                      // local pointer on parent process
     700    uint32_t         parent_pid;                      // parent process identifier
    614701    thread_t       * thread;                          // pointer on new thread
    615702    pthread_attr_t   attr;                            // main thread attributes
     
    618705        error_t          error;
    619706
    620         // get parent and .elf pathname from exec_info
     707        // get .elf pathname, parent_xp, and keep_pid flag from exec_info
    621708        path      = exec_info->path;
    622709    parent_xp = exec_info->parent_xp;
     710    keep_pid  = exec_info->keep_pid;
     711
     712process_dmsg("\n[DBG] %s : core[%x,%d] enters for path = %s\n",
     713__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path );
    623714
    624715    // get parent process cluster and local pointer
     
    627718    parent_pid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) );
    628719
    629     exec_dmsg("\n[DMSG] %s : thread %x on core[%x,%d] enters for path = %s\n",
    630     __FUNCTION__, CURRENT_THREAD->trdid, local_cxy, CURRENT_THREAD->core->lid , path );
    631 
    632     // create new process descriptor
    633     process = process_alloc();
    634 
    635     if( process == NULL )
    636     {
    637         printk("\n[ERROR] in %s : no memory / cluster = %x / ppid = %x / path = %s\n",
    638                __FUNCTION__ , local_cxy , parent_pid , path );
    639         return ENOMEM;
    640     }
    641 
    642     // get a pid from the local cluster
    643     error = cluster_pid_alloc( XPTR( local_cxy , process ) , &pid );
    644 
    645     if( error )
    646     {
    647         printk("\n[ERROR] in %s : cannot get PID / cluster = %x / ppid = %x / path = %s\n",
    648                __FUNCTION__ , local_cxy , parent_pid , path );
    649         process_free( process );
    650                 return ENOMEM;
    651     }
     720    // allocates memory for process descriptor
     721        process = process_alloc();
     722        if( process == NULL ) return -1;
     723
     724    // get PID
     725    if( keep_pid )    // keep parent PID
     726    {
     727        pid = parent_pid;
     728    }
     729    else              // get new PID from local cluster
     730    {
     731        error = cluster_pid_alloc( XPTR( local_cxy , process ) , &pid );
     732        if( error ) return -1;
     733    }
     734
     735process_dmsg("\n[DBG] %s : core[%x,%d] created process %x for path = %s\n",
     736__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid, path );
    652737
    653738    // initialize the process descriptor as the reference
    654739    process_reference_init( process , pid , parent_xp );
    655740
    656     exec_dmsg("\n[DMSG] %s : thread %x on core[%x,%d] created process %x / path = %s\n",
    657     __FUNCTION__, CURRENT_THREAD->trdid, local_cxy, CURRENT_THREAD->core->lid, pid, path );
     741process_dmsg("\n[DBG] %s : core[%x,%d] initialized process %x / path = %s\n",
     742__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid, path );
    658743
    659744    // initialize vfs_root and vfs_cwd from parent process
     
    670755                            XPTR( parent_cxy , &parent_ptr->fd_array) );
    671756
    672     exec_dmsg("\n[DMSG] %s : fd_array copied from process %x to process %x\n",
    673     __FUNCTION__, parent_pid , pid );
    674 
    675         // initialize signal manager TODO ??? [AG]
    676         // signal_manager_init( process );
     757process_dmsg("\n[DBG] %s :  core[%x,%d] copied fd_array for process %x\n",
     758__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid );
    677759
    678760    // register "code" and "data" vsegs as well as the process entry-point in VMM,
     
    682764        if( error )
    683765        {
    684                 printk("\n[ERROR] in %s : failed to access elf file for process %x / path = %s\n",
     766                printk("\n[ERROR] in %s : failed to access .elf file for process %x / path = %s\n",
    685767                       __FUNCTION__, pid , path );
    686768        process_destroy( process );
     
    688770        }
    689771
    690     exec_dmsg("\n[DMSG] %s : code and data vsegs registered for process %x / path = %s\n",
    691     __FUNCTION__ , pid , path );
     772process_dmsg("\n[DBG] %s : core[%x,%d] registered code/data vsegs for process %x / path = %s\n",
     773__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid, path );
    692774
    693775    // select a core in cluster
     
    709791        {
    710792                printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n",
    711                        __FUNCTION__, pid );
     793                       __FUNCTION__, pid , path );
    712794        process_destroy( process );
    713795        return error;
    714796        }
    715797
    716         exec_dmsg("\n[DMSG] %s : thread created for process %x on core %d in cluster %x\n",
    717                __FUNCTION__ , pid , core->lid , local_cxy );
    718 
    719 #if CONFIG_EXEC_DEBUG
    720 if( hal_time_stamp() > CONFIG_EXEC_DEBUG )
    721 {
    722     grdxt_print( &process->vmm.grdxt , GRDXT_TYPE_VSEG , process->pid );
    723     hal_gpt_print( &process->vmm.gpt , process->pid );
    724 }
    725 #endif
     798process_dmsg("\n[DBG] %s : core[%x,%d] created thread %x for process %x / path = %s\n",
     799__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, thread->trdid, pid, path  );
    726800
    727801    // update children list in parent process
     
    733807        thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );
    734808
    735     exec_dmsg("\n[DMSG] %s : exit for process %x\n",
    736                 __FUNCTION__, process->pid );
     809process_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s\n",
     810__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path );
    737811
    738812        return 0;
    739813
    740 }  // end proces_make_exec()
     814}  // end process_make_exec()
    741815
    742816//////////////////////////
     
    744818{
    745819    exec_info_t   exec_info;     // structure to be passed to process_make_exec()
    746 
    747         error_t   error1;
    748         error_t   error2;
    749         error_t   error3;
    750     xptr_t    stdin_xp;
    751     xptr_t    stdout_xp;
    752     xptr_t    stderr_xp;
    753     uint32_t  stdin_id;
    754     uint32_t  stdout_id;
    755     uint32_t  stderr_id;
    756 
    757         process_dmsg("\n[DMSG] %s : enters in cluster %x\n", __FUNCTION__ , local_cxy );
    758 
    759     // open stdin / stdout / stderr pseudo-files
    760         error1 = vfs_open( XPTR_NULL, CONFIG_DEV_STDIN , O_RDONLY, 0, &stdin_xp , &stdin_id  );
    761         error2 = vfs_open( XPTR_NULL, CONFIG_DEV_STDOUT, O_WRONLY, 0, &stdout_xp, &stdout_id );
    762         error3 = vfs_open( XPTR_NULL, CONFIG_DEV_STDERR, O_WRONLY, 0, &stderr_xp, &stderr_id );
    763 
    764         assert( ((error1 == 0) && (error2 == 0) && (error3 == 0)) , __FUNCTION__ ,
    765             "cannot open stdin/stdout/stderr pseudo files\n");
    766 
    767     assert( ((stdin_id == 0) && (stdout_id == 1) && (stderr_id == 2)) , __FUNCTION__ ,
    768             "bad indexes for stdin/stdout/stderr\n");
     820    xptr_t        parent_xp;     // extended pointer on parent process.
     821    error_t       error;
     822
     823process_dmsg("\n[DBG] %s : enters in cluster %x\n",
     824__FUNCTION__ , local_cxy );
     825
     826    // parent process is local kernel process
     827    parent_xp = XPTR( local_cxy , &process_zero );
    769828
    770829    // initialize the exec_info structure
    771     exec_info.parent_xp    = XPTR( local_cxy , &process_zero );
     830    exec_info.keep_pid     = false;
     831    exec_info.parent_xp    = parent_xp;
    772832    strcpy( exec_info.path , CONFIG_PROCESS_INIT_PATH );
    773833    exec_info.args_nr      = 0;
    774834    exec_info.envs_nr      = 0;
    775835
    776     // create process_init and thread_init
    777         error1 = process_make_exec( &exec_info );
    778 
    779         assert( (error1 == 0) , __FUNCTION__ , "cannot create process_init\n");
    780 
    781         process_dmsg("\n[DMSG] %s : exit in cluster %x\n", __FUNCTION__ , local_cxy );
     836    // initialize process_init and create thread_init
     837        error = process_make_exec( &exec_info );
     838
     839        if( error ) panic("cannot initialize process_init in cluster %x", local_cxy );
     840
     841process_dmsg("\n[DBG] %s : exit in cluster %x\n",
     842__FUNCTION__ , local_cxy );
    782843               
    783844    hal_fence();
  • trunk/kernel/kern/process.h

    r204 r407  
    143143{
    144144    xptr_t             parent_xp;      /*! extended pointer on parent process descriptor    */
     145    bool_t             keep_pid;       /*! keep parent PID if true / new PID if false       */
    145146
    146147    char               path[CONFIG_VFS_MAX_PATH_LENGTH];   /*!  .elf file path              */
     
    175176/*********************************************************************************************
    176177 * This function allocates memory and initializes the "process_init" descriptor and the
    177  * associated "thread_init" descriptor. It should be called once at the end of the kernel
    178  * initialisation procedure, by the kernel "process_zero".
     178 * associated "thread_init" descriptor in the local cluster. It is called once at the end
     179 * of the kernel initialisation procedure, by the local kernel process.
    179180 * The "process_init" is the first user process, and all other user processes will be forked
    180181 * from this process. The code executed by "process_init" is stored in a .elf file, whose
    181  * pathname is defined by the CONFIG_PROCESS_INIT_PATH argument. It uses fork/exec syscalls
    182  * to create the "shell" user process, and various other user daemon processes.
    183  * Practically, it builds the exec_info structure, registers the stdin / stdout / stderr
    184  * pseudo-file descriptors and the vfs_root and vfs_cwd in parent process_zero, and calls
    185  * the generic process_make_exec() function, that makes the real job.
     182 * pathname is defined by the CONFIG_PROCESS_INIT_PATH argument.
     183 * Practically, it builds the exec_info structure, and calls the process_make_exec()
     184 * function, that make the real job.
    186185 ********************************************************************************************/
    187186void process_init_create();
     
    253252 * and the associated main thread, from information found in the <exec_info> structure
    254253 * (defined in the process.h file), that must be built by the caller.
     254 * - If the <keep_pid> field is true, the new process inherits its PID from the parent PID.
     255 * - If the <keep_pid> field is false, a new PID is allocated from the local cluster manager.
    255256 * The new process inherits from the parent process (i) the open file descriptors, (ii) the
    256257 * vfs_root and the vfs_cwd inodes.
     
    268269
    269270
    270 /********************   Signal Management Operations   **************************************/
    271 
    272 /*********************************************************************************************
    273  * This function TODO [AG]
    274  ********************************************************************************************/
    275 void process_signal_handler( process_t * process );
    276 
    277 
    278271/********************   File Management Operations   ****************************************/
    279272
     
    287280/*********************************************************************************************
    288281 * This function uses as many remote accesses as required, to reset an entry in fd_array[],
    289  * in all clusters containing a copy. The entry is identified by the <file_id> argument.
     282 * in all clusters containing a copy. The entry is identified by the <fdid> argument.
    290283 * This function must be executed by a thread running reference cluster, that contains
    291284 * the complete list of process descriptors copies.
    292285 *********************************************************************************************
    293286 * @ process  : pointer on the local process descriptor.
    294  * @ file_id  : file descriptor index in the fd_array.
     287 * @ fdid     : file descriptor index in the fd_array.
    295288 ********************************************************************************************/
    296289void process_fd_remove( process_t * process,
    297                         uint32_t    file_id );
     290                        uint32_t    fdid );
    298291
    299292/*********************************************************************************************
     
    306299 *********************************************************************************************
    307300 * @ process  : pointer on the local process descriptor.
    308  * @ file_id  : file descriptor index in the fd_array.
     301 * @ fdid     : file descriptor index in the fd_array.
    309302 * @ return extended pointer on file descriptor if success / return XPTR_NULL if not found.
    310303 ********************************************************************************************/
    311304xptr_t process_fd_get_xptr( process_t * process,
    312                             uint32_t    file_id );
     305                            uint32_t    fdid );
    313306
    314307/*********************************************************************************************
     
    328321 *********************************************************************************************
    329322 * @ file_xp  : extended pointer on the file descriptor to be registered.
    330  * @ file_id  : [out] buffer for fd_array slot index.
     323 * @ fdid     : [out] buffer for fd_array slot index.
    331324 * @ return 0 if success / return EMFILE if array full.
    332325 ********************************************************************************************/
    333 error_t process_fd_register( xptr_t      file_xp,
    334                              uint32_t  * file_id );
     326error_t process_fd_register( process_t * process,
     327                             xptr_t      file_xp,
     328                             uint32_t  * fdid );
    335329
    336330/*********************************************************************************************
  • trunk/kernel/kern/rpc.c

    r406 r407  
    7676    &rpc_mapper_move_buffer_server,     // 24
    7777    &rpc_mapper_get_page_server,        // 25
    78     &rpc_undefined,                     // 26
    79     &rpc_undefined,                     // 27
     78    &rpc_vmm_create_vseg_server,        // 26
     79    &rpc_sched_display_server,          // 27
    8080    &rpc_undefined,                     // 28
    8181    &rpc_undefined,                     // 29
     
    9797                                page_t  ** page )      // out
    9898{
    99     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     99    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    100100    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    101101    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    115115
    116116    // get output arguments from RPC descriptor
    117     *page    = (page_t *)(intptr_t)rpc.args[1];
    118 
    119     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     117    *page = (page_t *)(intptr_t)rpc.args[1];
     118
     119    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    120120    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    121121    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    125125void rpc_pmem_get_pages_server( xptr_t xp )
    126126{
    127     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     127    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    128128    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    129129    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    142142    hal_remote_swd( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page );
    143143
    144     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     144    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    145145    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    146146    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    157157                                   pid_t     * pid )     // out
    158158{
    159     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     159    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    160160    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    161161    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    178178    *error  = (error_t)rpc.args[2];     
    179179
    180     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     180    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    181181    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    182182    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    190190    pid_t       pid;       // output : process identifier
    191191
    192     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     192    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    193193    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    194194    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    209209    hal_remote_sw( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)pid );
    210210
    211     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     211    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    212212    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    213213    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    224224                              error_t     * error )   // out
    225225{
    226     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     226    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    227227    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    228228    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    244244    *error  = (error_t)rpc.args[1];     
    245245
    246     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     246    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    247247    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    248248    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    256256    error_t       error;     // local error error status
    257257
    258     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     258    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    259259    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    260260    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    278278    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
    279279
    280     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     280    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    281281    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    282282    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    291291void rpc_process_kill_client( process_t * process )
    292292{
    293     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     293    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    294294    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    295295    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    325325    }
    326326
    327     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     327    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    328328    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    329329    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    336336    process_t * process; 
    337337
    338     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     338    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    339339    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    340340    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    360360    }
    361361
    362     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     362    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    363363    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    364364    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    379379                                    error_t        * error )      // out
    380380{
    381     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     381    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    382382    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    383383    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    387387    // initialise RPC descriptor header
    388388    rpc_desc_t  rpc;
    389     rpc.index    = RPC_THREAD_USER_CREATE;
    390     rpc.response = 1;
     389    rpc.index     = RPC_THREAD_USER_CREATE;
     390    rpc.response  = 1;
    391391
    392392    // set input arguments in RPC descriptor
     
    403403    *error     = (error_t)rpc.args[5];
    404404
    405     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     405    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    406406    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    407407    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    421421    error_t          error;
    422422
    423     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     423    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    424424    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    425425    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    442442                       sizeof(pthread_attr_t) );
    443443   
    444     assert( (attr_copy.cxy == local_cxy) , __FUNCTION__ , "bad target cluster\n" );
    445 
    446444    // call kernel function
    447445    error = thread_user_create( pid,
     
    453451    // set output arguments
    454452    thread_xp = XPTR( local_cxy , thread_ptr );
    455     hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
    456     hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp );
    457 
    458     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     453    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)thread_xp );
     454    hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
     455
     456    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    459457    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    460458    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    473471                                      error_t * error )      // out
    474472{
    475     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     473    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    476474    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    477475    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    496494    *error     = (error_t)rpc.args[4];
    497495
    498     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     496    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    499497    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    500498    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    509507    error_t          error;   
    510508
    511     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     509    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    512510    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    513511    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    533531    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp );
    534532
    535     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     533    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    536534    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    537535    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    547545                             uint32_t    sig_id )    // in
    548546{
    549     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     547    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    550548    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    551549    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    565563    rpc_send_sync( cxy , &rpc );
    566564
    567     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     565    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    568566    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    569567    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    576574    uint32_t     sig_id;   // signal index
    577575
    578     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     576    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    579577    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    580578    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    591589    signal_rise( process , sig_id );
    592590
    593     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     591    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    594592    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    595593    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    613611                                  error_t      * error )     // out
    614612{
    615     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     613    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    616614    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    617615    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    641639    *error    = (error_t)rpc.args[9];
    642640
    643     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     641    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    644642    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    645643    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    660658    error_t          error;
    661659
    662     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     660    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    663661    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    664662    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    693691    hal_remote_swd( XPTR( client_cxy , &desc->args[9] ) , (uint64_t)error );
    694692
    695     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     693    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    696694    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    697695    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    706704                                   struct vfs_inode_s * inode )
    707705{
    708     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     706    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    709707    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    710708    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    723721    rpc_send_sync( cxy , &rpc );
    724722
    725     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     723    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    726724    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    727725    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    733731    vfs_inode_t * inode;
    734732
    735     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     733    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    736734    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    737735    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    747745    vfs_inode_destroy( inode );
    748746
    749     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     747    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    750748    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    751749    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    764762                                   error_t              * error )       // out
    765763{
    766     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     764    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    767765    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    768766    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    787785    *error     = (error_t)rpc.args[4];
    788786
    789     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     787    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    790788    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    791789    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    803801    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
    804802
    805     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     803    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    806804    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    807805    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    829827    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
    830828
    831     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     829    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    832830    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    833831    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    843841                                    vfs_dentry_t * dentry )
    844842{
    845     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     843    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    846844    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    847845    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    860858    rpc_send_sync( cxy , &rpc );
    861859
    862     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     860    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    863861    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    864862    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    870868    vfs_dentry_t * dentry;
    871869
    872     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     870    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    873871    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    874872    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    884882    vfs_dentry_destroy( dentry );
    885883
    886     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     884    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    887885    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    888886    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    901899                                 error_t              * error )      // out
    902900{
    903     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     901    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    904902    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    905903    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    923921    *error   = (error_t)rpc.args[3];
    924922
    925     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     923    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    926924    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    927925    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    936934    error_t       error;
    937935
    938     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     936    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    939937    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    940938    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    957955    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
    958956
    959     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     957    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    960958    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    961959    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    970968                                  vfs_file_t * file )
    971969{
    972     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     970    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    973971    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    974972    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    987985    rpc_send_sync( cxy , &rpc );
    988986
    989     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     987    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    990988    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    991989    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    997995    vfs_file_t * file;
    998996
    999     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     997    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    1000998    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    1001999    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    10111009    vfs_file_destroy( file );
    10121010
    1013     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1011    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    10141012    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    10151013    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    10271025                                error_t     * error )          // out
    10281026{
    1029     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1027    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    10301028    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    10311029    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    10491047    *error   = (error_t)rpc.args[3];
    10501048
    1051     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1049    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    10521050    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    10531051    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    10641062    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
    10651063
    1066     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1064    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    10671065    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    10681066    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    10871085    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
    10881086
    1089     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1087    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    10901088    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    10911089    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    11011099                                     error_t     * error )     // out
    11021100{
    1103     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1101    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    11041102    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    11051103    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    11211119    *error   = (error_t)rpc.args[1];
    11221120
    1123     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1121    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    11241122    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    11251123    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    11321130    vfs_inode_t * inode;
    11331131
    1134     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1132    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    11351133    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    11361134    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    11491147    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
    11501148
    1151     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1149    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    11521150    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    11531151    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    11621160                                   mapper_t * mapper,    // in
    11631161                                   uint32_t   first,     // in
    1164                                    uint32_t   page,      // in
     1162                                   uint32_t   index,     // in
    11651163                                   uint32_t * cluster,   // out
    11661164                                   error_t  * error )    // out
    11671165{
    1168     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1166    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    11691167    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    11701168    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    11801178    rpc.args[0] = (uint64_t)(intptr_t)mapper;
    11811179    rpc.args[1] = (uint64_t)first;
    1182     rpc.args[2] = (uint64_t)page;
     1180    rpc.args[2] = (uint64_t)index;
    11831181
    11841182    // register RPC request in remote RPC fifo
     
    11891187    *error   = (error_t)rpc.args[4];
    11901188
    1191     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1189    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    11921190    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    11931191    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    11991197    mapper_t    * mapper;
    12001198    uint32_t      first;
    1201     uint32_t      page;
     1199    uint32_t      index;
    12021200    uint32_t      cluster;
    12031201    error_t       error;
    12041202
    1205     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1203    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    12061204    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    12071205    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    12141212    mapper = (mapper_t *)(intptr_t)hal_remote_lpt( XPTR( client_cxy , &desc->args[0] ) );
    12151213    first  = (uint32_t)            hal_remote_lw ( XPTR( client_cxy , &desc->args[1] ) );
    1216     page   = (uint32_t)            hal_remote_lw ( XPTR( client_cxy , &desc->args[2] ) );
     1214    index  = (uint32_t)            hal_remote_lw ( XPTR( client_cxy , &desc->args[2] ) );
    12171215
    12181216    // call the kernel function
    1219     error = fatfs_get_cluster( mapper , first , page , &cluster );
     1217    error = fatfs_get_cluster( mapper , first , index , &cluster );
    12201218
    12211219    // set output argument
     
    12231221    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
    12241222
    1225     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1223    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    12261224    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    12271225    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    12391237                              error_t   * error )      // out
    12401238{
    1241     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1239    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    12421240    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    12431241    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    12611259    *error   = (error_t)rpc.args[3];
    12621260
    1263     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1261    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    12641262    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    12651263    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    12751273    error_t       error;
    12761274
    1277     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1275    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    12781276    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    12791277    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    12951293    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
    12961294
    1297     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1295    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    12981296    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    12991297    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    13091307                             process_t * process,  // in
    13101308                             vpn_t       vpn,      // in
     1309                             bool_t      cow,      // in
    13111310                             uint32_t  * attr,     // out
    13121311                             ppn_t     * ppn,      // out
    13131312                             error_t   * error )   // out
    13141313{
    1315     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1314    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    13161315    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    13171316    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    13271326    rpc.args[0] = (uint64_t)(intptr_t)process;
    13281327    rpc.args[1] = (uint64_t)vpn;
     1328    rpc.args[2] = (uint64_t)cow;
    13291329
    13301330    // register RPC request in remote RPC fifo (blocking function)
     
    13321332
    13331333    // get output argument from rpc descriptor
    1334     *attr  = (uint32_t)rpc.args[2];
    1335     *ppn   = (ppn_t)rpc.args[3];
    1336     *error = (error_t)rpc.args[4];
    1337 
    1338     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1334    *attr  = (uint32_t)rpc.args[3];
     1335    *ppn   = (ppn_t)rpc.args[4];
     1336    *error = (error_t)rpc.args[5];
     1337
     1338    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    13391339    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    13401340    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    13461346    process_t   * process;
    13471347    vpn_t         vpn;
     1348    bool_t        cow;
    13481349    uint32_t      attr;
    13491350    ppn_t         ppn;
    13501351    error_t       error;
    13511352
    1352     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1353    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    13531354    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    13541355    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    13611362    process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
    13621363    vpn     = (vpn_t)                hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     1364    cow     = (bool_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
    13631365   
    13641366    // call local kernel function
    1365     error = vmm_get_pte( process , vpn , &attr , &ppn );
     1367    error = vmm_get_pte( process , vpn , cow , &attr , &ppn );
    13661368
    13671369    // set output argument "attr" & "ppn" to client RPC descriptor
    1368     hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)attr );
    1369     hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)ppn );
    1370     hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
    1371 
    1372     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1370    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)attr );
     1371    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)ppn );
     1372    hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
     1373
     1374    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    13731375    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    13741376    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    13841386                           xptr_t *   buf_xp )     // out
    13851387{
    1386     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1388    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    13871389    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    13881390    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    14041406    *buf_xp = (xptr_t)rpc.args[1];
    14051407
    1406     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1408    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    14071409    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    14081410    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    14121414void rpc_kcm_alloc_server( xptr_t xp )
    14131415{
    1414     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1416    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    14151417    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    14161418    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    14331435    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp );
    14341436
    1435     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1437    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    14361438    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    14371439    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    14471449                          uint32_t   kmem_type )   // in
    14481450{
    1449     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1451    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    14501452    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    14511453    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    14651467    rpc_send_sync( cxy , &rpc );
    14661468
    1467     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1469    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    14681470    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    14691471    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    14731475void rpc_kcm_free_server( xptr_t xp )
    14741476{
    1475     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1477    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    14761478    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    14771479    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    14911493    kmem_free( &req );
    14921494
    1493     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1495    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    14941496    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    14951497    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    15101512                                    error_t  * error )        // out
    15111513{
    1512     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1514    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    15131515    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    15141516    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    15351537    *error     = (error_t)rpc.args[6];
    15361538
    1537     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1539    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    15381540    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    15391541    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    15521554    error_t    error;
    15531555
    1554     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1556    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    15551557    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    15561558    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    15921594    hal_remote_swd( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)error );
    15931595
    1594     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1596    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    15951597    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    15961598    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    16071609                                 page_t         ** page )      // out
    16081610{
    1609     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1611    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    16101612    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    16111613    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    16281630    *page = (page_t *)(intptr_t)rpc.args[2];
    16291631
    1630     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1632    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    16311633    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    16321634    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    16361638void rpc_mapper_get_page_server( xptr_t xp )
    16371639{
    1638     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1640    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    16391641    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    16401642    CURRENT_THREAD->core->lid , hal_time_stamp() );
     
    16541656    hal_remote_swd( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page );
    16551657
    1656     rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    1657     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    1658     CURRENT_THREAD->core->lid , hal_time_stamp() );
    1659 }
    1660 
     1658    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1659    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1660    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1661}
     1662
     1663/////////////////////////////////////////////////////////////////////////////////////////
     1664// [26]          Marshaling functions attached to RPC_VMM_CREATE_VSEG
     1665/////////////////////////////////////////////////////////////////////////////////////////
     1666
     1667////////////////////////////////////////////////////////
     1668void rpc_vmm_create_vseg_client( cxy_t              cxy,
     1669                                 struct process_s * process,
     1670                                 vseg_type_t        type,
     1671                                 intptr_t           base,
     1672                                 uint32_t           size,
     1673                                 uint32_t           file_offset,
     1674                                 uint32_t           file_size,
     1675                                 xptr_t             mapper_xp,
     1676                                 cxy_t              vseg_cxy,
     1677                                 struct vseg_s   ** vseg )
     1678{
     1679    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1680    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1681    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1682
     1683    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     1684
     1685    // initialise RPC descriptor header
     1686    rpc_desc_t  rpc;
     1687    rpc.index    = RPC_VMM_CREATE_VSEG;
     1688    rpc.response = 1;
     1689
     1690    // set input arguments in RPC descriptor
     1691    rpc.args[0] = (uint64_t)(intptr_t)process;
     1692    rpc.args[1] = (uint64_t)type;
     1693    rpc.args[2] = (uint64_t)base;
     1694    rpc.args[3] = (uint64_t)size;
     1695    rpc.args[4] = (uint64_t)file_offset;
     1696    rpc.args[5] = (uint64_t)file_size;
     1697    rpc.args[6] = (uint64_t)mapper_xp;
     1698    rpc.args[7] = (uint64_t)vseg_cxy;
     1699
     1700    // register RPC request in remote RPC fifo (blocking function)
     1701    rpc_send_sync( cxy , &rpc );
     1702
     1703    // get output values from RPC descriptor
     1704    *vseg = (vseg_t *)(intptr_t)rpc.args[8];
     1705
     1706    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1707    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1708    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1709}
     1710
     1711////////////////////////////////////////////
     1712void rpc_vmm_create_vseg_server( xptr_t xp )
     1713{
     1714    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1715    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1716    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1717
     1718    // get client cluster identifier and pointer on RPC descriptor
     1719    cxy_t        cxy  = (cxy_t)GET_CXY( xp );
     1720    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
     1721
     1722    // get input arguments from client RPC descriptor
     1723    process_t * process     = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
     1724    vseg_type_t type        = (vseg_type_t)(uint32_t)hal_remote_lwd( XPTR(cxy , &desc->args[1]));
     1725    intptr_t    base        = (intptr_t)             hal_remote_lwd( XPTR(cxy , &desc->args[2]));
     1726    uint32_t    size        = (uint32_t)             hal_remote_lwd( XPTR(cxy , &desc->args[3]));
     1727    uint32_t    file_offset = (uint32_t)             hal_remote_lwd( XPTR(cxy , &desc->args[4]));
     1728    uint32_t    file_size   = (uint32_t)             hal_remote_lwd( XPTR(cxy , &desc->args[5]));
     1729    xptr_t      mapper_xp   = (xptr_t)               hal_remote_lwd( XPTR(cxy , &desc->args[6]));
     1730    cxy_t       vseg_cxy    = (cxy_t)(uint32_t)      hal_remote_lwd( XPTR(cxy , &desc->args[7]));
     1731   
     1732    // call local kernel function
     1733    vseg_t * vseg = vmm_create_vseg( process,
     1734                                     type,
     1735                                     base,
     1736                                     size,
     1737                                     file_offset,
     1738                                     file_size,
     1739                                     mapper_xp,
     1740                                     vseg_cxy );
     1741
     1742    // set output arguments into client RPC descriptor
     1743    hal_remote_swd( XPTR( cxy , &desc->args[8] ) , (uint64_t)(intptr_t)vseg );
     1744
     1745    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1746    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1747    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1748}
     1749
     1750/////////////////////////////////////////////////////////////////////////////////////////
     1751// [27]          Marshaling functions attached to RPC_SCHED_DISPLAY
     1752/////////////////////////////////////////////////////////////////////////////////////////
     1753
     1754////////////////////////////////////////////////////////
     1755void rpc_sched_display_client( cxy_t              cxy,
     1756                               lid_t              lid)
     1757{
     1758    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1759    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1760    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1761
     1762    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     1763
     1764    // initialise RPC descriptor header
     1765    rpc_desc_t  rpc;
     1766    rpc.index    = RPC_SCHED_DISPLAY;
     1767    rpc.response = 1;
     1768
     1769    // set input arguments in RPC descriptor
     1770    rpc.args[0] = (uint64_t)lid;
     1771
     1772    // register RPC request in remote RPC fifo (blocking function)
     1773    rpc_send_sync( cxy , &rpc );
     1774
     1775    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1776    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1777    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1778}
     1779
     1780//////////////////////////////////////////
     1781void rpc_sched_display_server( xptr_t xp )
     1782{
     1783    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1784    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1785    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1786
     1787    // get client cluster identifier and pointer on RPC descriptor
     1788    cxy_t        cxy  = (cxy_t)GET_CXY( xp );
     1789    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
     1790
     1791    // get input arguments from client RPC descriptor
     1792    lid_t lid = (lid_t)hal_remote_lw( XPTR(cxy , &desc->args[0]));
     1793   
     1794    // call local kernel function
     1795    sched_display( lid );
     1796
     1797    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1798    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1799    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1800}
    16611801
    16621802/***************************************************************************************/
     
    16681808                    rpc_desc_t * rpc )
    16691809{
    1670     uint32_t   cores;
    16711810    error_t    error;
    1672     bool_t     first;
    1673     reg_t      sr_save;
    1674 
    1675     rpc_dmsg("\n[DMSG] %s : enter / client_cxy = %x / server_cxy = %x / cycle %d\n",
    1676     __FUNCTION__ , local_cxy , server_cxy , hal_time_stamp() );
    1677 
    1678     // allocate and initialise an extended pointer on the RPC descriptor
     1811
     1812    thread_t * this = CURRENT_THREAD;
     1813    core_t   * core = this->core;
     1814
     1815    // register client thread pointer and core lid in RPC descriptor
     1816    rpc->thread    = this;
     1817    rpc->lid       = core->lid;
     1818
     1819    // build an extended pointer on the RPC descriptor
    16791820        xptr_t   desc_xp = XPTR( local_cxy , rpc );
    16801821
    16811822    // get local pointer on rpc_fifo in remote cluster, with the
    1682     // assumption that rpc_fifo pddresses are identical in all clusters
    1683     rpc_fifo_t * rf = &LOCAL_CLUSTER->rpc_fifo;
     1823    // assumption that local pointers are identical in all clusters
     1824    remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
    16841825
    16851826        // try to post an item in remote fifo
     
    16871828    do
    16881829    {
    1689         error = remote_fifo_put_item( XPTR( server_cxy , &rf->fifo ),
    1690                                       (uint64_t )desc_xp,
    1691                                       &first );
     1830        error = remote_fifo_put_item( XPTR( server_cxy , rpc_fifo ),
     1831                                      (uint64_t )desc_xp );
    16921832            if ( error )
    16931833        {
     
    16951835            __FUNCTION__ , local_cxy , server_cxy );
    16961836
    1697             if( thread_can_yield() ) sched_yield( NULL );
     1837            if( thread_can_yield() ) sched_yield();
    16981838        }
    16991839    }
    17001840    while( error );
    17011841 
    1702     rpc_dmsg("\n[DMSG] %s : RPC %l registered / server_cxy = %x / cycle %d\n",
    1703     __FUNCTION__ , desc_xp , server_cxy , hal_time_stamp() );
     1842    hal_fence();
    17041843       
    1705     // send IPI to remote CP0, if this is the first RPC in remote FIFO,
    1706     // and there is no CPU is in kernel mode in server cluster.
    1707         if( first )
    1708         {
    1709         // get number of cores in kernel mode in server cluster
    1710         cores = hal_remote_lw( XPTR( server_cxy , &LOCAL_CLUSTER->cores_in_kernel ) );
    1711 
    1712                 if( cores == 0 ) // no core in kernel mode in server
    1713                 {
    1714                     dev_pic_send_ipi( server_cxy , 0 );
    1715 
    1716                     rpc_dmsg("\n[DMSG] %s : IPI sent / client_cxy = %x / server_cxy = %x\n",
    1717             __FUNCTION__, local_cxy , server_cxy );
    1718         }
    1719         }
    1720 
    1721         // enable IRQs to allow incoming RPC and avoid deadlock
    1722         hal_enable_irq( &sr_save );
    1723 
    1724     // the server thread poll the response slot until RPC completed
    1725     // TODO this could be replaced by a descheduling policy... [AG]
    1726     while( rpc->response ) asm volatile( "nop" );
    1727 
    1728     // restore IRQs
    1729         hal_restore_irq( sr_save );
    1730 
    1731     rpc_dmsg("\n[DMSG] %s : completed / client_cxy = %x / server_cxy = %x / cycle %d\n",
    1732     __FUNCTION__ , local_cxy , server_cxy , hal_time_stamp() );
    1733 
     1844    // send IPI to the remote core corresponding to the client core
     1845        dev_pic_send_ipi( server_cxy , core->lid );
     1846
     1847    // wait RPC completion:
     1848    // - busy waiting policy during kernel_init, or if threads cannot yield
     1849    // - block and deschedule in all other cases
     1850
     1851    if( (this->type == THREAD_IDLE) || (thread_can_yield() == false) ) // busy waiting
     1852    {
     1853
     1854grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s busy waiting after registering RPC\n"
     1855"        rpc = %d / server = %x / cycle %d\n",
     1856__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ,
     1857rpc->index , server_cxy , hal_time_stamp() );
     1858
     1859        while( rpc->response ) hal_fixed_delay( 100 );
     1860   
     1861grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s exit after RPC completion\n",
     1862__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) );
     1863
     1864    }
     1865    else                                                              // block & deschedule
     1866    {
     1867
     1868grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s deschedule after registering RPC\n"
     1869"        rpc = %d / server = %x / cycle %d\n",
     1870__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ,
     1871rpc->index , server_cxy , hal_time_stamp() );
     1872
     1873        thread_block( this , THREAD_BLOCKED_RPC );
     1874        sched_yield();
     1875
     1876grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s resumes after RPC completion\n",
     1877__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) );
     1878
     1879    }
     1880
     1881    // check response available
     1882    assert( (rpc->response == 0) , __FUNCTION__, "illegal RPC response\n" );
     1883
     1884    // acknowledge the IPI sent by the server
     1885    dev_pic_ack_ipi();
     1886   
    17341887}  // end rpc_send_sync()
    17351888
     
    17401893/***************************************************************************************/
    17411894
    1742 ///////////////////////////////////////////
    1743 void rpc_fifo_init( rpc_fifo_t * rpc_fifo )
    1744 {
    1745         rpc_fifo->count       = 0;
    1746         rpc_fifo->owner       = 0;
    1747         local_fifo_init( &rpc_fifo->fifo );
    1748 }
    1749 
    1750 /////////////////////////////////////////////
    1751 void rpc_execute_all( rpc_fifo_t * rpc_fifo )
    1752 {
    1753         xptr_t         xp;             // extended pointer on RPC descriptor
    1754         uint32_t       count;          // handled RPC request counter
    1755         thread_t     * this;           // pointer on this RPC thread
    1756     core_t       * core;           // pointer on core running this thread
    1757     rpc_desc_t   * desc;           // pointer on RPC descriptor
    1758     uint32_t       index;          // RPC index
    1759     cxy_t          client_cxy;     // client cluster identifier
    1760         error_t        error;
    1761      
    1762         this  = CURRENT_THREAD;
    1763     core  = this->core;   
    1764         count = 0;
    1765 
    1766     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    1767     __FUNCTION__, this->trdid, local_cxy, core->lid , hal_time_stamp() );
     1895////////////////
     1896void rpc_check()
     1897{
     1898    error_t         error;
     1899    thread_t      * thread; 
     1900    uint32_t        sr_save;
     1901
     1902    bool_t          found    = false;
     1903        thread_t      * this     = CURRENT_THREAD;
     1904    core_t        * core     = this->core;
     1905    scheduler_t   * sched    = &core->scheduler;
     1906        remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
     1907
     1908grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s / cycle %d\n",
     1909__FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() );
     1910
     1911    // interrupted thread not preemptable during RPC chek
     1912        hal_disable_irq( &sr_save );
     1913
     1914    // check RPC FIFO not empty and no RPC thread handling it 
     1915        if( (rpc_fifo->owner == 0) && (local_fifo_is_empty(rpc_fifo) == false) )
     1916    {
     1917        // search one non blocked RPC thread   
     1918        list_entry_t * iter;
     1919        LIST_FOREACH( &sched->k_root , iter )
     1920        {
     1921            thread = LIST_ELEMENT( iter , thread_t , sched_list );
     1922            if( (thread->type == THREAD_RPC) && (thread->blocked == 0 ) )
     1923            {
     1924                found = true;
     1925                break;
     1926            }
     1927        }
     1928
     1929        // create new RPC thread if not found   
     1930        if( found == false )                   
     1931        {
     1932            error = thread_kernel_create( &thread,
     1933                                          THREAD_RPC,
     1934                                                      &rpc_thread_func,
     1935                                          NULL,
     1936                                                      this->core->lid );
     1937                if( error )
     1938            {
     1939                printk("\n[WARNING] in %s : no memory for new RPC thread in cluster %x\n",
     1940                __FUNCTION__ , local_cxy );
     1941            }
     1942            else
     1943            {
     1944                // unblock created RPC thread
     1945                thread->blocked = 0;
     1946
     1947                // update core descriptor counter 
     1948                    hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 );
     1949
     1950grpc_dmsg("\n[DBG] %s : core [%x,%d] creates a new RPC thread %x / cycle %d\n",
     1951__FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );
     1952
     1953            }
     1954        }
     1955    }
     1956
     1957grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s deschedules / cycle %d\n",
     1958__FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() );
     1959
     1960    // interrupted thread deschedule always           
     1961        sched_yield();
     1962
     1963grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s resume / cycle %d\n",
     1964__FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() );
     1965
     1966    // interrupted thread restore IRQs after resume
     1967        hal_restore_irq( sr_save );
     1968
     1969} // end rpc_check()
     1970
     1971
     1972//////////////////////
     1973void rpc_thread_func()
     1974{
     1975    uint32_t     count;       // handled RPC requests counter
     1976    error_t      empty;       // local RPC fifo state
     1977    xptr_t       desc_xp;     // extended pointer on RPC request
     1978    cxy_t        desc_cxy;    // RPC request cluster (client)
     1979    rpc_desc_t * desc_ptr;    // RPC request local pointer
     1980    uint32_t     index;       // RPC request index
     1981    uint32_t     responses;   // number of responses received by client
     1982    thread_t   * thread_ptr;  // local pointer on client thread
     1983    lid_t        core_lid;    // local index of client core
    17681984 
    1769     // handle up to CONFIG_RPC_PENDING_MAX requests before exit
    1770         do
    1771     {
    1772             error = local_fifo_get_item( &rpc_fifo->fifo, (uint64_t *)&xp );
    1773 
    1774                 if ( error == 0 )  // One RPC request successfully extracted from RPC_FIFO
     1985    // makes RPC thread not preemptable
     1986        hal_disable_irq( NULL );
     1987 
     1988        thread_t      * this     = CURRENT_THREAD;
     1989        remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
     1990
     1991    // two embedded loops:
     1992    // - external loop : "infinite" RPC thread
     1993    // - internal loop : handle up to CONFIG_RPC_PENDING_MAX RPC requests
     1994 
     1995        while(1)  // external loop
     1996        {
     1997        // try to take RPC_FIFO ownership
     1998        if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) )
    17751999        {
    1776             // get client cluster identifier and pointer on RPC descriptor
    1777             client_cxy = (cxy_t)GET_CXY( xp );
    1778             desc       = (rpc_desc_t *)GET_PTR( xp );
    1779 
    1780             // get rpc index from RPC descriptor
    1781                 index = hal_remote_lw( XPTR( client_cxy , &desc->index ) );
    1782 
    1783             rpc_dmsg("\n[DMSG] %s : thread %x on core [%x,%d] / rpc = %d\n",
    1784                      __FUNCTION__ , this->trdid , core->lid , local_cxy , index );
    1785 
    1786             // call the relevant server function
    1787             rpc_server[index]( xp );
    1788 
    1789             // increment handled RPC counter
    1790                 count++;
    1791 
    1792             // notify RPC completion as required
    1793             hal_remote_atomic_add( XPTR( client_cxy , &desc->response ) , -1 );
    1794                 }
     2000            // initializes RPC requests counter
     2001            count = 0;
     2002
     2003            // acknowledge local IPI
     2004            dev_pic_ack_ipi();
     2005
     2006                    // exit internal loop in three cases:
     2007            // - RPC fifo is empty
     2008            // - ownership has been lost (because descheduling)
     2009            // - max number of RPCs is reached
     2010                while( 1 )  // internal loop
     2011            {
     2012                    empty = local_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp );
     2013
     2014                    if ( empty == 0 ) // one RPC request found
     2015                {
     2016                    // get client cluster and pointer on RPC descriptor
     2017                    desc_cxy = (cxy_t)GET_CXY( desc_xp );
     2018                    desc_ptr = (rpc_desc_t *)GET_PTR( desc_xp );
     2019
     2020                    // get rpc index from RPC descriptor
     2021                        index = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->index ) );
     2022
     2023grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / starts rpc %d / cycle %d\n",
     2024__FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() );
     2025
     2026                    // call the relevant server function
     2027                    rpc_server[index]( desc_xp );
     2028
     2029grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / completes rpc %d / cycle %d\n",
     2030__FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() );
     2031
     2032                    // increment handled RPC counter
     2033                        count++;
     2034
     2035                    // decrement response counter in RPC descriptor
     2036                    responses = hal_remote_atomic_add(XPTR( desc_cxy, &desc_ptr->response ), -1);
     2037
     2038                    // unblock client thread  and send IPI to client core if last response
     2039                    if( responses == 1 )
     2040                    {
     2041                        // get pointer on client thread and unblock it
     2042                        thread_ptr = (thread_t *)hal_remote_lpt(XPTR(desc_cxy,&desc_ptr->thread));
     2043                        thread_unblock( XPTR(desc_cxy,thread_ptr) , THREAD_BLOCKED_RPC );
     2044
     2045                        hal_fence();
     2046
     2047                        // get client core lid and send IPI
     2048                        core_lid = hal_remote_lw(XPTR(desc_cxy, &desc_ptr->lid));
     2049                            dev_pic_send_ipi( desc_cxy , core_lid );
     2050                    }
     2051                        }
    17952052       
    1796                 // exit loop in three cases:
    1797         // - fifo is empty
    1798         // - look has been released (because descheduling)
    1799         // - max number of RPCs has been reached
    1800                 if( error ||
    1801             (rpc_fifo->owner != this->trdid) ||
    1802             (count > CONFIG_RPC_PENDING_MAX) ) break;
    1803         }
    1804     while( 1 );
    1805 
    1806     // update RPC_FIFO global counter
    1807         rpc_fifo->count += count;
    1808 
    1809 }  // end rpc_execute_all()
     2053                // chek exit condition
     2054                        if( local_fifo_is_empty( rpc_fifo )  ||
     2055                    (rpc_fifo->owner != this->trdid) ||
     2056                    (count >= CONFIG_RPC_PENDING_MAX) ) break;
     2057                } // end internal loop
     2058
     2059            // release rpc_fifo ownership if not lost
     2060            if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0;
     2061        }
     2062
     2063        // sucide if too many RPC threads in cluster
     2064        if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX )
     2065            {
     2066
     2067grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) suicide at cycle %d\n",
     2068__FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
     2069
     2070            // update RPC threads counter
     2071                hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 );
     2072
     2073            // suicide
     2074                thread_exit();
     2075            }
     2076
     2077grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) deschedules / cycle %d\n",
     2078__FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
     2079
     2080        // deschedule without blocking
     2081        sched_yield();
     2082
     2083grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) resumes / cycle %d\n",
     2084__FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
     2085
     2086        } // end external loop
     2087
     2088} // end rpc_thread_func()
     2089
     2090
     2091
     2092
     2093
     2094
     2095
     2096
     2097
     2098/* deprecated [AG] 29/09/2017
    18102099
    18112100////////////////////////////////////////////////////
    1812 error_t rpc_activate_thread( rpc_fifo_t * rpc_fifo )
     2101error_t rpc_activate_thread( remote_fifo_t * rpc_fifo )
    18132102{
    18142103        core_t      * core;
     
    18272116
    18282117    assert( (this->trdid == rpc_fifo->owner) , __FUNCTION__ ,
    1829           "calling thread is not RPC_FIFO owner\n" );
     2118    "calling thread is not RPC_FIFO owner\n" );
    18302119
    18312120    // makes the calling thread not preemptable
     
    18332122        hal_disable_irq( &sr_save );
    18342123
    1835     // search a free RPC thread (must be in THREAD_BLOCKED_IDLE state)   
     2124grpc_dmsg("\n[DBG] %s : core[%x,%d] enter at cycle %d\n",
     2125__FUNCTION__ , local_cxy , core->lid , hal_time_stamp() );
     2126
     2127    // search one non blocked RPC thread   
    18362128    list_entry_t * iter;
    18372129    LIST_FOREACH( &sched->k_root , iter )
    18382130    {
    18392131        thread = LIST_ELEMENT( iter , thread_t , sched_list );
    1840         if( (thread->type == THREAD_RPC) && (thread->blocked == THREAD_BLOCKED_IDLE ) )
     2132        if( (thread->type == THREAD_RPC) && (thread->blocked == 0 ) )
    18412133        {
    18422134            found = true;
     
    18452137    }
    18462138
    1847     if( found )                    // activate this idle RPC thread     
     2139    if( found == false )                    // create new RPC thread     
    18482140    {
    1849         // unblock it
    1850         thread->blocked = 0;
    1851 
    1852         rpc_dmsg("\n[DMSG] %s : activate RPC thread %x on core [%x,%d] / cycle %d\n",
    1853                           __FUNCTION__ , thread , core->gid , local_cxy , hal_time_stamp() );
    1854     }
    1855     else                           // create a new RPC thread
    1856     {
    1857         // create new thread
    18582141        error = thread_kernel_create( &thread,
    18592142                                      THREAD_RPC,
     
    18692152        }
    18702153
    1871         // unblock new thread
     2154        // unblock thread
    18722155        thread->blocked = 0;
    18732156
     
    18752158            hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 );
    18762159
    1877         rpc_dmsg("\n[DMSG] %s : create RPC thread %x on core [%x,%d] / cycle %d\n",
    1878                           __FUNCTION__ , thread->trdid, local_cxy, core->lid, hal_time_stamp() );
     2160grpc_dmsg("\n[DBG] %s : core [%x,%d] creates RPC thread %x at cycle %d\n",
     2161__FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );
     2162
    18792163    }
    1880 
    1881     // update owner in rpc_fifo
     2164    else                           // create a new RPC thread
     2165    {
     2166
     2167grpc_dmsg("\n[DBG] %s : core[%x,%d] activates RPC thread %x at cycle %d\n",
     2168__FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );
     2169
     2170    }
     2171
     2172    // update rpc_fifo owner
    18822173    rpc_fifo->owner = thread->trdid;
    18832174
    1884     // current thread switch to RPC thread 
    1885         sched_yield( thread );
     2175    // current thread deschedule           
     2176        sched_yield();
    18862177
    18872178    // restore IRQs for the calling thread
     
    18932184}  // end rpc_activate_thread()
    18942185
    1895 //////////////////
    1896 bool_t rpc_check()
     2186////////////////
     2187void rpc_check()
    18972188{
    18982189        thread_t   * this     = CURRENT_THREAD;
    1899         rpc_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
     2190        remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
    19002191    error_t      error;
    19012192
    1902     rpc_dmsg("\n[DMSG] %s : enter / thread %x / cluster %x / cycle %d\n",
    1903              __FUNCTION__ , this->trdid , local_cxy , hal_time_stamp() );
     2193grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / enter at cycle %d\n",
     2194__FUNCTION__ , local_cxy , this->core->lid , this->trdid , hal_time_stamp() );
    19042195
    19052196    // calling thread does nothing if light lock already taken or FIFO empty 
    19062197        if( (rpc_fifo->owner != 0) || (local_fifo_is_empty( &rpc_fifo->fifo )) )
    19072198    {
    1908         rpc_dmsg("\n[DMSG] %s : exit do nothing / thread %x / cluster %x / cycle %d\n",
    1909                  __FUNCTION__ , this->trdid , local_cxy , hal_time_stamp() );
    1910 
    1911         return false;
     2199
     2200grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / exit do nothing at cycle %d\n",
     2201__FUNCTION__ , local_cxy , this->core->lid , this->trdid , hal_time_stamp() );
     2202
     2203        return;
    19122204    }
    19132205
     
    19222214
    19232215            printk("\n[ERROR] in %s : no memory to create a RPC thread for core %d"
    1924                    " in cluster %x => do nothing\n",
    1925                    __FUNCTION__ , CURRENT_CORE->lid , local_cxy );
     2216            " in cluster %x => do nothing\n",
     2217            __FUNCTION__ , CURRENT_CORE->lid , local_cxy );
    19262218        }
    19272219
    1928         rpc_dmsg("\n[DMSG] %s : exit after RPC thread activation / "
    1929                  "thread %x / cluster %x / cycle %d\n",
    1930                  __FUNCTION__ , this->trdid , local_cxy , hal_time_stamp() );
    1931 
    1932         return true;
     2220        return;
    19332221    }
    19342222    else  // light lock taken by another thread
    19352223    {
    1936         rpc_dmsg("\n[DMSG] %s : exit do nothing / thread %x / cluster %x / cycle %d\n",
    1937                  __FUNCTION__ , this->trdid , local_cxy , hal_time_stamp() );
    1938 
    1939         return false;
     2224
     2225grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / exit do nothing at cycle %d\n",
     2226__FUNCTION__ , local_cxy , this->core->lid , this->trdid , hal_time_stamp() );
     2227
     2228        return;
    19402229    }
    19412230} // end rpc_check()
     
    19492238 
    19502239        thread_t   * this     = CURRENT_THREAD;
    1951         rpc_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
    1952 
    1953     rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    1954              __FUNCTION__, this->trdid, local_cxy, this->core->lid, hal_time_stamp() );
    1955 
    1956     // this infinite loop is not preemptable
    1957     // the RPC thread deschedule only when the RPC_FIFO is empty
     2240        remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
     2241
    19582242        while(1)
    19592243        {
    19602244        // check fifo ownership (ownership should be given by rpc_activate()
    1961         if( this->trdid != rpc_fifo->owner )
    1962         {
    1963             panic("thread %x on core[%x,%d] not owner of RPC_FIFO",
    1964                   this->trdid, local_cxy, this->core->lid );
    1965         }
     2245        assert( (this->trdid == rpc_fifo->owner) , __FUNCTION__ ,
     2246        "thread %x on core[%x,%d] not owner of RPC_FIFO / owner = %x\n",
     2247        this->trdid, local_cxy, this->core->lid , rpc_fifo->owner );
    19662248 
    19672249        // executes pending RPC(s)
    19682250        rpc_execute_all( rpc_fifo );
    19692251
    1970         // release rpc_fifo ownership (can be lost during RPC execution)
     2252        // release rpc_fifo ownership if required
     2253        // (this ownership can be lost during RPC execution)
    19712254        if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0;
    19722255
    1973 
    1974         //  block and deschedule or sucide
    1975                 if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX )
     2256        //  deschedule or sucide
     2257                if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX )  // suicide
    19762258                {
    1977             rpc_dmsg("\n[DMSG] %s : RPC thread %x on core[%x,%d] suicide / cycle %d\n",
    1978                     __FUNCTION__, this->trdid, local_cxy, this->core->lid, hal_time_stamp() );
     2259
     2260grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / suicide at cycle %d\n",
     2261__FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
    19792262
    19802263            // update core descriptor counter
     
    19842267                        thread_exit();
    19852268                }
    1986         else
     2269        else                                                       // deschedule
    19872270        {
    1988             rpc_dmsg("\n[DMSG] %s : RPC thread %x on core[%x,%d] blocks / cycle %d\n",
    1989                         __FUNCTION__, this->trdid, local_cxy, this->core->lid, hal_time_stamp() );
    1990 
    1991                     thread_block( this , THREAD_BLOCKED_IDLE );
    1992             sched_yield( NULL );
    1993 
    1994                     rpc_dmsg("\n[DMSG] %s : RPC thread %x wake up on core[%x,%d] / cycle %d\n",
    1995                 __FUNCTION__, this->trdid, local_cxy, this->core->lid, hal_time_stamp() );
     2271
     2272grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / deschedule at cycle %d\n",
     2273__FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
     2274
     2275            sched_yield();
     2276
     2277grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / wake up at cycle %d\n",
     2278__FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
     2279
    19962280        }
    19972281        } // end while
    19982282} // end rpc_thread_func()
    19992283
     2284*/
     2285
     2286
  • trunk/kernel/kern/rpc.h

    r401 r407  
    3030#include <bits.h>
    3131#include <spinlock.h>
     32#include <vseg.h>
    3233#include <remote_fifo.h>
    3334
     
    8283    RPC_MAPPER_MOVE_BUFFER     = 24,
    8384    RPC_MAPPER_GET_PAGE        = 25,
     85    RPC_VMM_CREATE_VSEG        = 26,
     86    RPC_SCHED_DISPLAY          = 27,
    8487
    8588    RPC_MAX_INDEX              = 30,
     
    100103typedef struct rpc_desc_s
    101104{
    102         rpc_index_t       index;       // index of requested RPC service
    103         volatile uint32_t response;    // response valid when 0
    104     uint64_t          args[10];    // input/output arguments buffer
     105        rpc_index_t         index;       /*! index of requested RPC service           */
     106        volatile uint32_t   response;    /*! response valid when 0                    */
     107    struct thread_s   * thread;      /*! local pointer on client thread           */
     108    uint32_t            lid;         /*! index of core running the calling thread */
     109    uint64_t            args[10];    /*! input/output arguments buffer            */
    105110}
    106111rpc_desc_t;
    107 
    108 /***********************************************************************************
    109  * This structure defines the RPC fifo, containing a remote_fifo, the owner RPC
    110  * thread TRDID (used as a light lock), and the intrumentation counter.
    111  *
    112  * Implementation note: the TRDID is a good owner identifier, because all
    113  * RPC threads in a given cluster belong to the same process_zero kernel process,
    114  * and RPC threads cannot have local index LTID = 0.
    115  **********************************************************************************/
    116 
    117 typedef struct rpc_fifo_s
    118 {
    119         trdid_t           owner;       // owner thread / 0 if no owner
    120         uint64_t          count;       // total number of received RPCs (instrumentation)
    121         remote_fifo_t     fifo;        // embedded remote fifo
    122 }
    123 rpc_fifo_t;
    124 
    125112
    126113/**********************************************************************************/
     
    149136
    150137/***********************************************************************************
    151  * This function initialises the local RPC fifo and the lock protecting readers.
    152  * The number of slots is defined by the CONFIG_REMOTE_FIFO_SLOTS parameter.
    153  * Each slot contains an extended pointer on the RPC descriptor.
    154  ***********************************************************************************
    155  * @ rf     : pointer on the local RPC fifo.
    156  **********************************************************************************/
    157 void rpc_fifo_init( rpc_fifo_t * rf );
    158 
    159 /***********************************************************************************
    160138 * This function is the entry point for RPC handling on the server side.
    161  * It is executed by a core receiving an IPI.
    162  * It checks the RPC fifo, try to take the light-lock and activates (or creates)
    163  * an RPC thread in case of success.
    164  ***********************************************************************************
    165  * @ returns true if success / false otherwise.
    166  **********************************************************************************/
    167 bool_t rpc_check();
     139 * It is executed by a core receiving an IPI, and each time the core enters,
     140 * or exit the kernel to handle .
     141 * It does nothing and return if the RPC_FIFO is empty.
     142 * The calling thread checks if it exist at least one non-blocked RPC thread,
     143 * creates a new RPC if required, and deschedule to allow the RPC thead to execute.
     144 **********************************************************************************/
     145void rpc_check();
    168146
    169147/***********************************************************************************
    170148 * This function contains the loop to execute all pending RPCs on the server side.
    171  * It should be called with irq disabled and after light lock acquisition.
     149 * It is called by the rpc_thread_func() function with irq disabled, and after
     150 * RPC_FIFO ownership acquisition.
    172151 ***********************************************************************************
    173152 * @ rpc_fifo  : pointer on the local RPC fifo
    174153 **********************************************************************************/
    175 void rpc_execute_all( rpc_fifo_t * rpc_fifo );
    176 
    177 /**********************************************************************************
    178  * This function is called by any thread running on any core in any cluster,
    179  * that detected a non-empty RPC_FIFO and got the RPC_FIFO ownership.
    180  * It activates one RPC thread, and immediately switches to the RPC thread.
    181  * It gets the first free RPC thread from the core free-list, or creates a new one
    182  * when the core free-list is empty.
    183  ***********************************************************************************
    184  * @ rpc_fifo : pointer on the non-empty RPC fifo.
    185  * @ return 0 if success / return ENOMEM if error.
    186  **********************************************************************************/
    187 error_t rpc_activate_thread( rpc_fifo_t * rpc_fifo );
    188 
    189 /***********************************************************************************
    190  * This function contains the infinite loop executed by each RPC thread.
     154void rpc_execute_all( remote_fifo_t * rpc_fifo );
     155
     156/***********************************************************************************
     157 * This function contains the infinite loop executed by a RPC thread.
    191158 **********************************************************************************/
    192159void rpc_thread_func();
     
    266233 ***********************************************************************************
    267234 * @ cxy       : server cluster identifier.
    268  * @ attr      : [in]  pointer on pthread_attr_t in client cluster.
    269  * @ thread_xp : [out] pointer on buffer for thread extended pointer.
     235 * @ attr      : [in]  local pointer on pthread_attr_t in client cluster.
     236 * @ thread_xp : [out] buffer for thread extended pointer.
    270237 * @ error     : [out] error status (0 if success).
    271238 **********************************************************************************/
     
    274241                                    void                  * start_func,
    275242                                    void                  * start_arg,
    276                                     struct pthread_attr_s * attr,
     243                                    pthread_attr_t        * attr,
    277244                                    xptr_t                * thread_xp,
    278245                                    error_t               * error );
     
    499466
    500467/***********************************************************************************
    501  * [21] The RPC_VMM_GET_PTE returns in the "ppn" and "attr" arguments the PTE value
    502  * for a given VPN in a given process.
     468 * [21] The RPC_VMM_GET_PTE returns in the <ppn> and <attr> arguments the PTE value
     469 * for a given <vpn> in a given <process> (page_fault or copy_on_write event).
    503470 * The server cluster is supposed to be the reference cluster, and the vseg
    504471 * containing the VPN must be registered in the reference VMM.
    505  * It returns an error if physical memory cannot be allocated for the PTE2,
     472 * It returns an error if physical memory cannot be allocated for the missing PTE2,
    506473 * or for the missing page itself.
    507474 ***********************************************************************************
     
    509476 * @ process : [in]   pointer on process descriptor in server cluster.
    510477 * @ vaddr   : [in]   virtual address to be searched.
     478 * @ cow     : [in]   "copy_on_write" event if true / "page_fault" event if false.
    511479 * @ attr    : [out]  address of buffer for attributes.
    512480 * @ ppn     : [out]  address of buffer for PPN.
     
    516484                             struct process_s * process,
    517485                             vpn_t              vpn,
     486                             bool_t             cow,
    518487                             uint32_t         * attr,
    519488                             ppn_t            * ppn,
     
    601570void rpc_mapper_get_page_server( xptr_t xp );
    602571
     572/***********************************************************************************
     573 * [26] The RPC_VMM_CREATE_VSEG allows a client thread to request the remote
     574 * reference cluster of a given process to allocate and register in the reference
     575 * process VMM a new vseg descriptor.
     576 * On the server side, this RPC uses the vmm_create_vseg() function, and returns
     577 * to the client the local pointer on the created vseg descriptor.
     578 ***********************************************************************************
     579 * @ cxy         : server cluster identifier.
     580 * @ process     : [in]  local pointer on process descriptor in server.
     581 * @ type        : [in]  vseg type.
     582 * @ base        : [in]  base address (unused for dynamically allocated vsegs).
     583 * @ size        : [in]  number of bytes.
     584 * @ file_offset : [in]  offset in file (for CODE, DATA, FILE types).
     585 * @ file_size   : [in]  can be smaller than size for DATA type.
     586 * @ mapper_xp   : [in]  extended pointer on mapper (for CODE, DATA, FILE types).
     587 * @ vseg_cxy    : [in]  target cluster for mapping (if not data type).
     588 * @ vseg        : [out] local pointer on vseg descriptor / NULL if failure.
     589 **********************************************************************************/
     590void rpc_vmm_create_vseg_client( cxy_t              cxy,
     591                                 struct process_s * process,
     592                                 vseg_type_t        type,
     593                                 intptr_t           base,
     594                                 uint32_t           size,
     595                                 uint32_t           file_offset,
     596                                 uint32_t           file_size,
     597                                 xptr_t             mapper_xp,
     598                                 cxy_t              vseg_cxy,
     599                                 struct vseg_s   ** vseg );
     600
     601void rpc_vmm_create_vseg_server( xptr_t xp );
     602
     603/***********************************************************************************
     604 * [27] The RPC_SCHED_DISPLAY allows a client thread to request the display
     605 * of a remote scheduler, identified by the <lid> argument.
     606 ***********************************************************************************
     607 * @ cxy         : server cluster identifier.
     608 * @ lid         : [in]  local index of target core in client cluster.
     609 **********************************************************************************/
     610void rpc_sched_display_client( cxy_t              cxy,
     611                               lid_t              lid );
     612
     613void rpc_sched_display_server( xptr_t xp );
     614
    603615#endif
  • trunk/kernel/kern/scheduler.c

    r406 r407  
    2424#include <kernel_config.h>
    2525#include <hal_types.h>
     26#include <hal_switch.h>
    2627#include <hal_irqmask.h>
    2728#include <hal_context.h>
     
    3839
    3940extern chdev_directory_t    chdev_dir;            // allocated in kernel_init.c file
    40 
     41extern uint32_t             switch_save_sr[];     // allocated in kernel_init.c file
    4142
    4243////////////////////////////////
     
    127128}  // end sched_remove()
    128129
    129 ///////////////////////////////////////////
    130 void sched_kill_thread( thread_t * thread )
    131 {
    132     // check thread locks
    133     if( thread_can_yield() == false )
    134     {
    135         panic("thread %x in process %x on core[%x][%d]"
    136               " did not released all locks",
    137               thread->trdid , thread->process->pid,
    138               local_cxy , thread->core->lid );
    139     }
    140 
    141     // remove thread from scheduler
    142     sched_remove_thread( thread );
    143 
    144     // reset the THREAD_SIG_KILL signal
    145     thread_reset_signal( thread , THREAD_SIG_KILL );
    146 
    147 }  // end sched_kill_thread()
    148 
    149130////////////////////////////////////////
    150131thread_t * sched_select( core_t * core )
     
    154135    scheduler_t * sched = &core->scheduler;
    155136
    156     sched_dmsg("\n[DMSG] %s : enter core[%x,%d] / cycle %d\n",
    157     __FUNCTION__ , local_cxy , core->lid , hal_time_stamp() );
    158 
    159137    // take lock protecting sheduler lists
    160138    spinlock_lock( &sched->lock );
     
    163141    list_entry_t * last;
    164142
    165     // first : scan the kernel threads list if not empty
     143    // first loop : scan the kernel threads list if not empty
    166144    if( list_is_empty( &sched->k_root ) == false )
    167145    {
     
    179157            thread = LIST_ELEMENT( current , thread_t , sched_list );
    180158
    181             // return thread if not idle_thread and runnable
    182             if( (thread->type != THREAD_IDLE) && (thread->blocked == 0) )
     159            // analyse kernel thread type
     160            switch( thread->type )
    183161            {
    184                 // release lock
    185                 spinlock_unlock( &sched->lock );
    186 
    187                 sched_dmsg("\n[DMSG] %s : exit core[%x,%d] / k_thread = %x / cycle %d\n",
    188                 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );
    189 
    190                 return thread;
    191             }
     162                case THREAD_IDLE: // skip IDLE thread
     163                break;
     164
     165                case THREAD_RPC:  // RPC thread if non blocked and FIFO non-empty
     166                if( (thread->blocked == 0) &&
     167                    (local_fifo_is_empty( &LOCAL_CLUSTER->rpc_fifo ) == 0) )
     168                {
     169                    spinlock_unlock( &sched->lock );
     170                    return thread;
     171                }
     172                break;
     173
     174                default:          // DEV thread if non blocked
     175                if( thread->blocked == 0 )
     176                {
     177                    spinlock_unlock( &sched->lock );
     178                    return thread;
     179                }
     180                break;
     181            }  // end switch type
    192182        }
    193183        while( current != last );
    194184    }
    195185
    196     // second : scan the user threads list if not empty
     186    // second loop : scan the user threads list if not empty
    197187    if( list_is_empty( &sched->u_root ) == false )
    198188    {
     
    213203            if( thread->blocked == 0 )
    214204            {
    215                 // release lock
    216205                spinlock_unlock( &sched->lock );
    217 
    218                 sched_dmsg("\n[DMSG] %s : exit core[%x,%d] / u_thread = %x / cycle %d\n",
    219                 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );
    220206                return thread;
    221207            }
     
    224210    }
    225211
    226     // release lock
     212    // third : return idle thread if no runnable thread
    227213    spinlock_unlock( &sched->lock );
    228 
    229     sched_dmsg("\n[DMSG] %s : exit core[%x,%d] / idle = %x / cycle %d\n",
    230     __FUNCTION__ , local_cxy , core->lid , sched->idle->trdid , hal_time_stamp() );
    231 
    232     // third : return idle thread if no runnable thread
    233214    return sched->idle;
    234215
    235216}  // end sched_select()
     217
     218///////////////////////////////////////////
     219void sched_kill_thread( thread_t * thread )
     220{
     221    // check locks
     222    if( thread_can_yield() == false )
     223    {
     224        panic("locks not released for thread %x in process %x on core[%x][%d]",
     225        thread->trdid , thread->process->pid, local_cxy , thread->core->lid );
     226    }
     227
     228    // remove thread from scheduler
     229    sched_remove_thread( thread );
     230
     231    // reset the THREAD_SIG_KILL signal
     232    thread_reset_signal( thread , THREAD_SIG_KILL );
     233
     234    // detached thread can suicide
     235    if( thread->signals & THREAD_SIG_SUICIDE )
     236    {
     237        assert( (thread->flags & THREAD_FLAG_DETACHED), __FUNCTION__,
     238        "thread must be detached in case of suicide\n" );
     239
     240        // remove thread from process
     241        process_remove_thread( thread );
     242
     243        // release memory for thread descriptor
     244        thread_destroy( thread );
     245    }
     246}  // end sched_kill_thread()
    236247
    237248//////////////////////////////////////////
     
    242253    scheduler_t  * sched = &core->scheduler;
    243254
    244     sched_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d]\n",
    245     __FUNCTION__, CURRENT_THREAD->trdid , local_cxy , core->lid );
    246 
    247255    // take lock protecting threads lists
    248256    spinlock_lock( &sched->lock );
     
    252260    {
    253261        thread = LIST_ELEMENT( iter , thread_t , sched_list );
    254         if( thread->signals & THREAD_SIG_KILL ) sched_kill_thread( thread );
     262        if( thread->signals ) sched_kill_thread( thread );
    255263    }
    256264
     
    259267    {
    260268        thread = LIST_ELEMENT( iter , thread_t , sched_list );
    261         if( thread->signals & THREAD_SIG_KILL ) sched_kill_thread( thread );
     269        if( thread->signals ) sched_kill_thread( thread );
    262270    }
    263271
     
    265273    spinlock_unlock( &sched->lock );
    266274
    267     sched_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d]\n",
    268     __FUNCTION__, CURRENT_THREAD->trdid , local_cxy , core->lid );
    269 
    270275} // end sched_handle_signals()
    271276
    272 ///////////////////////////////////
    273 void sched_yield( thread_t * next )
    274 {
    275     reg_t         sr_save;
    276 
     277//////////////////////////////////////
     278void sched_update( thread_t * current,
     279                   thread_t * next )
     280{
     281    scheduler_t * sched = &current->core->scheduler;
     282
     283    if( current->type == THREAD_USER ) sched->u_last = &current->sched_list;
     284    else                               sched->k_last = &current->sched_list;
     285
     286    sched->current = next;
     287}
     288
     289//////////////////
     290void sched_yield()
     291{
     292    thread_t    * next;
    277293    thread_t    * current = CURRENT_THREAD;
    278     core_t      * core    = current->core;
    279     scheduler_t * sched   = &core->scheduler;
    280 
    281     sched_dmsg("\n[DMSG] %s : thread %x on core[%x,%d] enter / cycle %d\n",
    282     __FUNCTION__, current->trdid, local_cxy, core->lid, hal_time_stamp() );
     294 
     295#if( CONFIG_SCHED_DEBUG & 0x1 )
     296if( hal_time_stamp() > CONFIG_SCHED_DEBUG ) sched_display( current->core->lid );
     297#endif
    283298
    284299    // delay the yield if current thread has locks
    285     if( thread_can_yield() == false )
     300    if( (current->local_locks != 0) || (current->remote_locks != 0) )
    286301    {
    287302        current->flags |= THREAD_FLAG_SCHED;
     
    289304    }
    290305
    291     // first loop on all threads to handle pending signals
    292     sched_handle_signals( core );
    293 
    294     // second loop on threads to select next thread if required
    295     if( next == NULL ) next = sched_select( core );
     306    // loop on threads to select next thread
     307    next = sched_select( current->core );
    296308
    297309    // check next thread attached to same core as the calling thread
    298     assert( (next->core == current->core), __FUNCTION__ , "next core != current core\n");
    299 
    300     // check next thread not blocked
    301     assert( (next->blocked == 0), __FUNCTION__ , "next thread is blocked\n");
     310    assert( (next->core == current->core), __FUNCTION__ ,
     311    "next core != current core\n");
     312
     313    // check next thread not blocked when type != IDLE
     314    assert( (next->blocked == 0) || (next->type = THREAD_IDLE) , __FUNCTION__ ,
     315    "next thread %x (%s) is blocked on core[%x,%d]\n",
     316    next->trdid , thread_type_str(next->type) , local_cxy , current->core->lid );
    302317
    303318    // switch contexts and update scheduler state if next != current
    304319        if( next != current )
    305320    {
    306         sched_dmsg("\n[DMSG] %s : trd %x (%s) on core[%x,%d] => trd %x (%s) / cycle %d\n",
    307         __FUNCTION__, current->trdid, thread_type_str(current->type), local_cxy, core->lid,
    308         next->trdid, thread_type_str(next->type), hal_time_stamp() );
    309 
    310         // calling thread desactivate IRQs
    311         hal_disable_irq( &sr_save );
     321        // current thread desactivate IRQs
     322        hal_disable_irq( &switch_save_sr[CURRENT_THREAD->core->lid] );
     323
     324sched_dmsg("\n[DBG] %s : core[%x,%d] / trd %x (%s) (%x,%x) => trd %x (%s) (%x,%x) / cycle %d\n",
     325__FUNCTION__, local_cxy, current->core->lid,
     326current, thread_type_str(current->type), current->process->pid, current->trdid,
     327next   , thread_type_str(next->type)   , next->process->pid   , next->trdid,
     328hal_time_stamp() );
    312329
    313330        // update scheduler
    314         if( current->type == THREAD_USER ) sched->u_last = &current->sched_list;
    315         else                               sched->k_last = &current->sched_list;
    316         sched->current = next;
    317 
    318         // handle FPU
     331        sched_update( current , next );
     332
     333        // handle FPU ownership
    319334            if( next->type == THREAD_USER )
    320335        {
    321                 if( next == core->fpu_owner )  hal_fpu_enable();
    322                 else                           hal_fpu_disable();
     336                if( next == current->core->fpu_owner )  hal_fpu_enable();
     337                else                                    hal_fpu_disable();
    323338        }
    324339
    325         // switch contexts
    326         hal_cpu_context_switch( current , next );
    327 
    328         // restore IRQs when calling thread resume
    329         hal_restore_irq( sr_save );
     340        // switch CPU from calling thread context to new thread context
     341        hal_do_cpu_switch( current->cpu_context, next->cpu_context );
     342
     343        // restore IRQs when next thread resume
     344        hal_restore_irq( switch_save_sr[CURRENT_THREAD->core->lid] );
    330345    }
    331346    else
    332347    {
    333         sched_dmsg("\n[DMSG] %s : thread %x on core[%x,%d] continue / cycle %d\n",
    334         __FUNCTION__, current->trdid, local_cxy, core->lid, hal_time_stamp() );
     348
     349sched_dmsg("\n[DBG] %s : core[%x,%d] / thread %x (%s) continue / cycle %d\n",
     350__FUNCTION__, local_cxy, current->core->lid, current->trdid,
     351thread_type_str(current->type) ,hal_time_stamp() );
     352
    335353    }
    336354}  // end sched_yield()
    337355
    338 ////////////////////
    339 void sched_display()
     356
     357///////////////////////////////
     358void sched_display( lid_t lid )
    340359{
    341360    list_entry_t * iter;
     
    343362    uint32_t       save_sr;
    344363
    345     thread_t     * current = CURRENT_THREAD;
    346     core_t       * core    = current->core;
     364    if( lid >= LOCAL_CLUSTER->cores_nr )
     365    {
     366        printk("\n[ERROR] in %s : illegal local index %d in cluster %x\n",
     367        __FUNCTION__ , lid , local_cxy );
     368        return;
     369    }
     370
     371    core_t       * core    = &LOCAL_CLUSTER->core_tbl[lid];
    347372    scheduler_t  * sched   = &core->scheduler;
    348373   
    349374    // get pointers on TXT0 chdev
    350     xptr_t    txt0_xp  = chdev_dir.txt[0];
     375    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
    351376    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
    352377    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     
    358383    remote_spinlock_lock_busy( lock_xp , &save_sr );
    359384
    360     nolock_printk("\n***** scheduler state for core[%x,%d]\n"
    361            "kernel_threads = %d / user_threads = %d / current = %x\n",
    362             local_cxy , core->lid,
    363             sched->k_threads_nr, sched->u_threads_nr, sched->current->trdid );
     385    nolock_printk("\n***** scheduler state for core[%x,%d] at cycle %d\n"
     386           "kernel_threads = %d / user_threads = %d / current = %x / idle = %x\n",
     387            local_cxy , core->lid, hal_time_stamp(),
     388            sched->k_threads_nr, sched->u_threads_nr,
     389            sched->current->trdid , sched->idle->trdid );
    364390
    365391    // display kernel threads
     
    367393    {
    368394        thread = LIST_ELEMENT( iter , thread_t , sched_list );
    369         nolock_printk(" - type = %s / trdid = %x / pid = %x / func = %x / blocked_vect = %x\n",
     395        nolock_printk(" - type = %s / trdid = %X / pid = %X / func = %X / blocked = %X\n",
    370396        thread_type_str( thread->type ), thread->trdid, thread->process->pid,
    371397        thread->entry_func, thread->blocked );
     
    376402    {
    377403        thread = LIST_ELEMENT( iter , thread_t , sched_list );
    378         nolock_printk(" - type = %s / trdid = %x / pid = %x / func = %x / blocked_vect = %x\n",
     404        nolock_printk(" - type = %s / trdid = %X / pid = %X / func = %X / blocked = %X\n",
    379405        thread_type_str( thread->type ), thread->trdid, thread->process->pid,
    380406        thread->entry_func, thread->blocked );
  • trunk/kernel/kern/scheduler.h

    r296 r407  
    7474
    7575/*********************************************************************************************
    76  * This function handles pending signals for all registered threads, and tries to make
    77  * a context switch for the core running the calling thread.
    78  * - If the <next> argument is not NULL, this next thread starts execution.
    79  * - If <next> is NULL, it calls the sched_select() function. If there is a runable thread
    80  *   (other than current thread or idle thread), this selected thread starts execution.
    81  * - If there is no other runable thread, the calling thread continues execution.
    82  * - If there is no runable thread, the idle thread is executed.
    83  *********************************************************************************************
    84  * @ next  : local pointer on next thread to run / call sched_select() if NULL.
     76 * This function handles pending signals for all registered threads, and calls the
     77 * sched_select() function to make a context switch for the core running the calling thread.
    8578 ********************************************************************************************/
    86 void sched_yield( struct thread_s * next );
     79void sched_yield();
    8780
    8881/*********************************************************************************************
     
    9689/*********************************************************************************************
    9790 * This function is used by the scheduler of a given core to actually kill a thread that has
    98  * the SIG_KILL signal set (following a thread_exit() or a thread_kill() event).
     91 * the SIG_KILL / SIG_SUICIDE signal set (following a thread_exit() or a thread_kill() event).
    9992 * - It checks that the thread has released all locks => panic otherwise...
    100  * - It detach the thread from the local process descriptor.
    10193 * - It removes the thread from the scheduler.
    102  * - It release physical memory allocated for thread descriptor.
     94 * - It reset the SIG_KILL signal to acknoledge the killer.
     95 * - In case of SIG_SUCIDE, it removes the detached thread from its process, and destroys it.
    10396 *********************************************************************************************
    10497 * @ thread  : local pointer on the thread descriptor.
     
    121114
    122115/*********************************************************************************************
    123  * This function display the internal state of the calling core scheduler.
     116 * This function display the internal state of the local core identified by its <lid>.
     117 *********************************************************************************************
     118 * @ lid      : local index of target core.
    124119 ********************************************************************************************/
    125 void sched_display();
     120void sched_display( lid_t lid );
    126121
    127122
  • trunk/kernel/kern/signal.c

    r406 r407  
    4444                hal_atomic_or( &thread->signals , (1 << sig_id) );
    4545
    46         signal_dmsg("\n[DMSG] %s : thread %x in process %x received signal %d\n",
     46        signal_dmsg("\n[DBG] %s : thread %x in process %x received signal %d\n",
    4747                    __FUNCTION__, thread->trdid , process->pid , sig_id );
    4848        }
     
    5959        thread_s * this = CURRENT_THREAD;
    6060
    61         printk("\n[DMSG] %s : threadReceived signal %d, pid %d, tid %x, core %d  [ KILLED ]\n",
     61        printk("\n[DBG] %s : threadReceived signal %d, pid %d, tid %x, core %d  [ KILLED ]\n",
    6262               sig,
    6363               this->process->pid,
  • trunk/kernel/kern/thread.c

    r406 r407  
    5757    else if( type == THREAD_RPC    ) return "RPC";
    5858    else if( type == THREAD_DEV    ) return "DEV";
    59     else if( type == THREAD_KERNEL ) return "KER";
    6059    else if( type == THREAD_IDLE   ) return "IDL";
    6160    else                             return "undefined";
     
    153152    }
    154153
     154    // compute thread descriptor size without kernel stack
     155    uint32_t desc_size = (intptr_t)(&thread->signature) - (intptr_t)thread + 4;
     156
    155157        // Initialize new thread descriptor
    156158    thread->trdid           = trdid;
     
    170172    thread->u_stack_base    = u_stack_base;
    171173    thread->u_stack_size    = u_stack_size;
    172     thread->k_stack_base    = (intptr_t)thread;
    173     thread->k_stack_size    = CONFIG_THREAD_DESC_SIZE;
     174    thread->k_stack_base    = (intptr_t)thread + desc_size;
     175    thread->k_stack_size    = CONFIG_THREAD_DESC_SIZE - desc_size;
    174176
    175177    thread->entry_func      = func;         // thread entry point
     
    178180    thread->signals         = 0;            // no pending signal
    179181    thread->errno           = 0;            // no error detected
    180     thread->fork_user       = 0;            // no fork required
    181     thread->fork_cxy        = 0;
     182    thread->fork_user       = 0;            // no user defined placement for fork
     183    thread->fork_cxy        = 0;            // user defined target cluster for fork
    182184
    183185    // thread blocked
     
    221223    vseg_t       * vseg;         // stack vseg
    222224
    223     thread_dmsg("\n[DMSG] %s : enters for process %x\n", __FUNCTION__ , pid );
     225    assert( (attr != NULL) , __FUNCTION__, "pthread attributes must be defined" );
    224226
    225227    // get process descriptor local copy
     
    234236
    235237    // select a target core in local cluster
    236     if( attr->attributes & PT_ATTR_CORE_DEFINED ) core_lid = attr->lid;
    237     else                                          core_lid = cluster_select_local_core();
    238 
    239     // check core local index
    240     if( core_lid >= LOCAL_CLUSTER->cores_nr )
    241     {
    242             printk("\n[ERROR] in %s : illegal core index attribute = %d\n",
    243                __FUNCTION__ , core_lid );
    244 
    245         return EINVAL;
     238    if( attr->attributes & PT_ATTR_CORE_DEFINED )
     239    {
     240        core_lid = attr->lid;
     241        if( core_lid >= LOCAL_CLUSTER->cores_nr )
     242        {
     243                printk("\n[ERROR] in %s : illegal core index attribute = %d\n",
     244            __FUNCTION__ , core_lid );
     245            return EINVAL;
     246        }
     247    }
     248    else
     249    {
     250        core_lid = cluster_select_local_core();
    246251    }
    247252
    248253    // allocate a stack from local VMM
    249     vseg = vmm_create_vseg( process, 0 , 0 , VSEG_TYPE_STACK );
     254    vseg = vmm_create_vseg( process,
     255                            VSEG_TYPE_STACK,
     256                            0,                 // size unused
     257                            0,                 // length unused
     258                            0,                 // file_offset unused
     259                            0,                 // file_size unused
     260                            XPTR_NULL,         // mapper_xp unused
     261                            local_cxy );
    250262
    251263    if( vseg == NULL )
     
    287299
    288300    // set DETACHED flag if required
    289     if( attr->attributes & PT_ATTR_DETACH ) thread->flags |= THREAD_FLAG_DETACHED;
     301    if( attr->attributes & PT_ATTR_DETACH )
     302    {
     303        thread->flags |= THREAD_FLAG_DETACHED;
     304    }
    290305
    291306    // allocate & initialize CPU context
    292         error = hal_cpu_context_create( thread );
    293 
    294     if( error )
     307        if( hal_cpu_context_create( thread ) )
    295308    {
    296309            printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ );
     
    300313    }
    301314
    302     // allocate & initialize FPU context
    303     error = hal_fpu_context_create( thread );
    304 
    305     if( error )
     315    // allocate  FPU context
     316    if( hal_fpu_context_alloc( thread ) )
    306317    {
    307318            printk("\n[ERROR] in %s : cannot create FPU context\n", __FUNCTION__ );
     
    311322    }
    312323
    313     thread_dmsg("\n[DMSG] %s : exit / trdid = %x / process %x / core = %d\n",
    314                 __FUNCTION__ , thread->trdid , process->pid , core_lid );
     324thread_dmsg("\n[DBG] %s : core[%x,%d] exit / trdid = %x / process %x / core = %d\n",
     325__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid,
     326thread->trdid , process->pid , core_lid );
    315327
    316328    *new_thread = thread;
     
    319331}  // end thread_user_create()
    320332
    321 //////////////////////////////////////////////
     333////////////////////////////////////////////////////
    322334error_t thread_user_fork( process_t * process,
     335                          intptr_t    stack_base,
     336                          uint32_t    stack_size,
    323337                          thread_t ** new_thread )
    324338{
    325339    error_t        error;
    326         thread_t     * thread;       // pointer on new thread descriptor
     340        thread_t     * child;       // pointer on new thread descriptor
    327341    lid_t          core_lid;     // selected core local index
    328         vseg_t       * vseg;         // stack vseg
    329 
    330     thread_dmsg("\n[DMSG] %s : enters\n", __FUNCTION__ );
    331 
    332     // allocate a stack from local VMM
    333     vseg = vmm_create_vseg( process, 0 , 0 , VSEG_TYPE_STACK );
    334 
    335     if( vseg == NULL )
    336     {
    337             printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ );
    338                 return ENOMEM;
    339     }
     342
     343thread_dmsg("\n[DBG] %s : core[%x,%d] enters\n",
     344__FUNCTION__ , local_cxy , core_lid );
    340345
    341346    // select a target core in local cluster
    342347    core_lid = cluster_select_local_core();
    343348
    344     // get pointer on calling thread descriptor
    345     thread_t * this = CURRENT_THREAD;
     349    // get pointer on parent thread descriptor
     350    thread_t * parent = CURRENT_THREAD;
    346351
    347352    // allocate memory for new thread descriptor
    348     thread = thread_alloc();
    349 
    350     if( thread == NULL )
     353    child = thread_alloc();
     354
     355    if( child == NULL )
    351356    {
    352357        printk("\n[ERROR] in %s : cannot allocate new thread\n", __FUNCTION__ );
    353         vmm_remove_vseg( vseg );
    354358        return ENOMEM;
    355359    }
    356360
    357361    // initialize thread descriptor
    358     error = thread_init( thread,
     362    error = thread_init( child,
    359363                         process,
    360364                         THREAD_USER,
    361                          this->entry_func,
    362                          this->entry_args,
     365                         parent->entry_func,
     366                         parent->entry_args,
    363367                         core_lid,
    364                          vseg->min,
    365                          vseg->max - vseg->min );
     368                         stack_base,
     369                         stack_size );
    366370
    367371    if( error )
    368372    {
    369373            printk("\n[ERROR] in %s : cannot initialize new thread\n", __FUNCTION__ );
    370         vmm_remove_vseg( vseg );
    371         thread_release( thread );
     374        thread_release( child );
    372375        return EINVAL;
    373376    }
    374377
    375     // set ATTACHED flag if set in this thread
    376     if( this->flags & THREAD_FLAG_DETACHED ) thread->flags = THREAD_FLAG_DETACHED;
    377 
    378     // allocate & initialize CPU context from calling thread
    379         error = hal_cpu_context_copy( thread , this );
    380 
    381     if( error )
    382     {
    383             printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ );
    384         vmm_remove_vseg( vseg );
    385         thread_release( thread );
     378    // return child pointer
     379    *new_thread = child;
     380
     381    // set DETACHED flag if required
     382    if( parent->flags & THREAD_FLAG_DETACHED ) child->flags = THREAD_FLAG_DETACHED;
     383
     384    // allocate CPU context for child thread
     385        if( hal_cpu_context_alloc( child ) )
     386    {
     387            printk("\n[ERROR] in %s : cannot allocate CPU context\n", __FUNCTION__ );
     388        thread_release( child );
    386389        return ENOMEM;
    387390    }
    388391
    389     // allocate & initialize FPU context from calling thread
    390         error = hal_fpu_context_copy( thread , this );
    391 
    392     if( error )
    393     {
    394             printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ );
    395         vmm_remove_vseg( vseg );
    396         thread_release( thread );
     392    // allocate FPU context for child thread
     393        if( hal_fpu_context_alloc( child ) )
     394    {
     395            printk("\n[ERROR] in %s : cannot allocate FPU context\n", __FUNCTION__ );
     396        thread_release( child );
    397397        return ENOMEM;
    398398    }
    399399
    400     thread_dmsg("\n[DMSG] %s : exit / thread %x for process %x on core %d in cluster %x\n",
    401                  __FUNCTION__, thread->trdid, process->pid, core_lid, local_cxy );
    402 
    403     *new_thread = thread;
     400    // copy kernel stack content from parent to child thread descriptor
     401    void * dst = (void *)(&child->signature) + 4;
     402    void * src = (void *)(&parent->signature) + 4;
     403    memcpy( dst , src , parent->k_stack_size );
     404
     405thread_dmsg("\n[DBG] %s : core[%x,%d] exit / created main thread %x for process %x\n",
     406__FUNCTION__, local_cxy , core_lid , child->trdid , process->pid );
     407
    404408        return 0;
    405409
     
    416420        thread_t     * thread;       // pointer on new thread descriptor
    417421
    418     thread_dmsg("\n[DMSG] %s : enter / for type %s on core[%x,%d] / cycle %d\n",
    419     __FUNCTION__ , thread_type_str( type ) , local_cxy , core_lid , hal_time_stamp() );
    420 
    421     assert( ( (type == THREAD_KERNEL) || (type == THREAD_RPC) ||
    422               (type == THREAD_IDLE)   || (type == THREAD_DEV) ) ,
    423               __FUNCTION__ , "illegal thread type" );
     422thread_dmsg("\n[DBG] %s : core[%x,%d] enters / type % / cycle %d\n",
     423__FUNCTION__ , local_cxy , core_lid , thread_type_str( type ) , hal_time_stamp() );
     424
     425    assert( ( (type == THREAD_IDLE) || (type == THREAD_RPC) || (type == THREAD_DEV) ) ,
     426    __FUNCTION__ , "illegal thread type" );
    424427
    425428    assert( (core_lid < LOCAL_CLUSTER->cores_nr) ,
     
    449452        hal_cpu_context_create( thread );
    450453
    451     thread_dmsg("\n[DMSG] %s : exit / trdid = %x / type = %s / core = [%x,%d] / cycle %d\n",
    452     __FUNCTION__ , thread->trdid , thread_type_str(type) ,
    453     local_cxy , core_lid , hal_time_stamp() );
     454thread_dmsg("\n[DBG] %s : core = [%x,%d] exit / trdid = %x / type %s / cycle %d\n",
     455__FUNCTION__, local_cxy, core_lid, thread->trdid, thread_type_str(type), hal_time_stamp() );
    454456
    455457    *new_thread = thread;
     
    465467                                            lid_t           core_lid )
    466468{
    467     assert( ( (type == THREAD_KERNEL) || (type == THREAD_RPC) ||
    468               (type == THREAD_IDLE)   || (type == THREAD_DEV) ) ,
    469               __FUNCTION__ , "illegal thread type" );
    470 
    471     if( core_lid >= LOCAL_CLUSTER->cores_nr )
    472     {
    473         panic("illegal core_lid / cores = %d / lid = %d / cxy = %x",
    474               LOCAL_CLUSTER->cores_nr , core_lid , local_cxy );
    475     }
     469    assert( (type == THREAD_IDLE) , __FUNCTION__ , "illegal thread type" );
     470
     471    assert( (core_lid < LOCAL_CLUSTER->cores_nr) , __FUNCTION__ , "illegal core index" );
    476472
    477473    error_t  error = thread_init( thread,
     
    487483
    488484    return error;
    489 }
     485
     486}  // end thread_kernel_init()
    490487
    491488///////////////////////////////////////////////////////////////////////////////////////
     
    502499    core_t     * core       = thread->core;
    503500
    504     thread_dmsg("\n[DMSG] %s : enters for thread %x in process %x / type = %s\n",
     501    thread_dmsg("\n[DBG] %s : enters for thread %x in process %x / type = %s\n",
    505502                __FUNCTION__ , thread->trdid , process->pid , thread_type_str( thread->type ) );
    506503
     
    556553        tm_end = hal_get_cycles();
    557554
    558         thread_dmsg("\n[DMSG] %s : exit for thread %x in process %x / duration = %d\n",
     555        thread_dmsg("\n[DBG] %s : exit for thread %x in process %x / duration = %d\n",
    559556                       __FUNCTION__, thread->trdid , process->pid , tm_end - tm_start );
    560 }
     557
     558}   // end thread_destroy()
    561559
    562560/////////////////////////////////////////////////
     
    609607{
    610608    hal_atomic_or( &thread->signals , mask );
     609    hal_fence();
    611610}
    612611
     
    616615{
    617616    hal_atomic_and( &thread->signals , ~mask );
    618 }
    619 
    620 //////////////////////////////////
    621 inline bool_t thread_is_joinable()
    622 {
    623     thread_t * this = CURRENT_THREAD;
    624     return( (this->brothers_list.next != XPTR_NULL) &&
    625             (this->brothers_list.pred != XPTR_NULL) );
    626 }
    627 
    628 //////////////////////////////////
    629 inline bool_t thread_is_runnable()
    630 {
    631     thread_t * this = CURRENT_THREAD;
    632     return( this->blocked == 0 );
     617    hal_fence();
    633618}
    634619
     
    650635    {
    651636        this->flags &= ~THREAD_FLAG_SCHED;
    652         sched_yield( NULL );
    653     }
    654 }
     637        sched_yield();
     638    }
     639
     640}  // end thread_check_sched()
     641
     642/////////////////////////////////////
     643void thread_block( thread_t * thread,
     644                   uint32_t   cause )
     645{
     646    // set blocking cause
     647    hal_atomic_or( &thread->blocked , cause );
     648    hal_fence();
     649
     650} // end thread_block()
     651
     652/////////////////////////////////////////
     653uint32_t thread_unblock( xptr_t   thread,
     654                         uint32_t cause )
     655{
     656    // get thread cluster and local pointer
     657    cxy_t      cxy = GET_CXY( thread );
     658    thread_t * ptr = (thread_t *)GET_PTR( thread );
     659
     660    // reset blocking cause
     661    uint32_t previous = hal_remote_atomic_and( XPTR( cxy , &ptr->blocked ) , ~cause );
     662    hal_fence();
     663
     664    // return a non zero value if the cause bit is modified
     665    return( previous & cause );
     666
     667}  // end thread_unblock()
    655668
    656669/////////////////////
     
    664677        if( !thread_can_yield() )
    665678        {
    666         printk("ERROR in %s : thread %x in process %x on core %d in cluster %x\n"
    667                " did not released all locks\n",
    668                __FUNCTION__ , this->trdid , this->process->pid ,
    669                CURRENT_CORE->lid , local_cxy );
     679        printk("ERROR in %s : locks not released for thread %x in process %x on core[%x,%d]\n",
     680        __FUNCTION__, this->trdid, this->process->pid, local_cxy, this->core->lid );
    670681        return EINVAL;
    671682    }
     
    686697
    687698    // deschedule
    688     sched_yield( NULL );
     699    sched_yield();
    689700    return 0;
    690 }
    691 
    692 /////////////////////////////////////
    693 void thread_block( thread_t * thread,
    694                    uint32_t   cause )
    695 {
    696     // set blocking cause
    697     hal_atomic_or( &thread->blocked , cause );
    698 }
    699 
    700 ////////////////////////////////////
    701 void thread_unblock( xptr_t   thread,
    702                     uint32_t cause )
    703 {
    704     // get thread cluster and local pointer
    705     cxy_t      cxy = GET_CXY( thread );
    706     thread_t * ptr = (thread_t *)GET_PTR( thread );
    707 
    708     // reset blocking cause
    709     hal_remote_atomic_and( XPTR( cxy , &ptr->blocked ) , ~cause );
    710 }
     701
     702}  // end thread_exit()
    711703
    712704/////////////////////////////////////
     
    721713    // send an IPI to schedule the target thread core.
    722714    dev_pic_send_ipi( local_cxy , target->core->lid );
    723 }
     715
     716}  // end thread_kill()
    724717
    725718///////////////////////
    726719void thread_idle_func()
    727720{
    728 #if CONFIG_IDLE_DEBUG
    729     lid_t  lid = CURRENT_CORE->lid;
    730 #endif
    731 
    732721    while( 1 )
    733722    {
    734         idle_dmsg("\n[DMSG] %s : core[%x][%d] goes to sleep at cycle %d\n",
    735                     __FUNCTION__ , local_cxy , lid , hal_get_cycles() );
    736 
    737         // force core to sleeping state
    738         //hal_core_sleep();
    739 
    740         idle_dmsg("\n[DMSG] %s : core[%x][%d] wake up at cycle %d\n",
    741                     __FUNCTION__ , local_cxy , lid , hal_get_cycles() );
    742 
    743         // force scheduling
    744         sched_yield( NULL );
     723        if( CONFIG_THREAD_IDLE_MODE_SLEEP ) // force core to low-power mode
     724        {
     725
     726idle_dmsg("\n[DBG] %s : core[%x][%d] goes to sleep at cycle %d\n",
     727__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_get_cycles() );
     728
     729            hal_core_sleep();
     730
     731idle_dmsg("\n[DBG] %s : core[%x][%d] wake up at cycle %d\n",
     732__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_get_cycles() );
     733
     734        }
     735        else                                // yield each ~ 100000 cycles
     736
     737        {
     738             hal_fixed_delay( 500000 );
     739        }
     740
     741        // force scheduling at each iteration
     742        sched_yield();
    745743   }
    746 }
     744}  // end thread_idle()
     745
    747746
    748747/////////////////////////////////////////////////
  • trunk/kernel/kern/thread.h

    r406 r407  
    2727
    2828#include <hal_types.h>
     29#include <shared_syscalls.h>
    2930#include <hal_special.h>
    3031#include <xlist.h>
     
    5152
    5253/***************************************************************************************
    53  * This defines the various pthread_attr_t attributes bit-vector.
    54  **************************************************************************************/
    55 
    56 /***************************************************************************************
    57  * This opaque structure contains the user defined attributes for a user thread.
    58  * It is passed as input argument to the thread_user_create() function.
    59  * It is set by the user application itself, using the pthread_attr_***() functions.
    60  * The currently supported attributes are defined below.
    61  **************************************************************************************/
    62 
    63 typedef struct pthread_attr_s
    64 {
    65         uint32_t    attributes;      /*! user defined attributes bit vector               */
    66         cxy_t       cxy;             /*! target cluster identifier                        */
    67         lid_t       lid;             /*! target core index                                */
    68 }
    69 pthread_attr_t;
    70 
    71 typedef enum
    72 {
    73     PT_ATTR_DETACH          = 0x0001,  /*! user defined not joinable                  */
    74     PT_ATTR_CLUSTER_DEFINED = 0x0002,  /*! user defined target cluster                */
    75     PT_ATTR_CORE_DEFINED    = 0x0004,  /*! user defined core index in cluster         */
    76 }
    77 pt_attributes_t;
    78 
    79 /***************************************************************************************
    8054 * This enum defines the thread types.
    8155 **************************************************************************************/
     
    8660        THREAD_RPC     = 1,          /*! kernel thread executing pending RPCs             */
    8761        THREAD_DEV     = 2,          /*! kernel thread executing I/O device commands      */
    88         THREAD_KERNEL  = 3,          /*! other kernel thread                              */
    89         THREAD_IDLE    = 4,          /*! kernel idle thread                               */
    90         THREAD_TYPES_NR
     62        THREAD_IDLE    = 3,          /*! kernel idle thread                               */
    9163}
    9264thread_type_t;
     
    10072#define THREAD_FLAG_JOIN         0x0004  /*! Parent thread made a join                */
    10173#define THREAD_FLAG_EXIT         0x0008  /*! This thread made an exit                 */
    102 #define THREAD_FLAG_SCHED        0x0010  /*! Descheduling required for this thread    */
     74#define THREAD_FLAG_SCHED        0x0010  /*! Scheduling required for this thread      */
    10375
    10476/***************************************************************************************
     
    10678 **************************************************************************************/
    10779
    108 #define THREAD_SIG_KILL          0x0001  /*! This thread must be destroyed ASAP       */
     80#define THREAD_SIG_KILL          0x0001  /*! This thread killed by another thread     */
     81#define THREAD_SIG_SUICIDE       0x0002  /*! This thread required exit                */
    10982
    11083/***************************************************************************************
     
    11689#define THREAD_BLOCKED_MAPPER    0x0004  /*! thread wait mapper                       */
    11790#define THREAD_BLOCKED_JOIN      0x0008  /*! thread blocked in join / wait exit       */
    118 #define THREAD_BLOCKED_EXIT      0x0010  /*! thread blocked in exit / wait join i     */
     91#define THREAD_BLOCKED_EXIT      0x0010  /*! thread blocked in exit / wait join       */
    11992#define THREAD_BLOCKED_KILL      0x0020  /*! thread received kill signal              */
    12093#define THREAD_BLOCKED_SEM       0x0040  /*! thread wait semaphore                    */
    12194#define THREAD_BLOCKED_PAGE      0x0080  /*! thread wait page access                  */
    12295#define THREAD_BLOCKED_USERSYNC  0x0100  /*! thread wait POSIX (cond/mutex/barrier)   */
    123 
    124 #define THREAD_BLOCKED_IDLE      0x1000  /*! thread RPC wait activation               */
     96#define THREAD_BLOCKED_RPC       0x0200  /*! thread wait RPC completion               */
     97
    12598#define THREAD_BLOCKED_DEV_QUEUE 0x2000  /*! thread DEV wait queue                    */
    12699#define THREAD_BLOCKED_DEV_ISR   0x4000  /*! thread DEV wait ISR                      */
     
    199172
    200173    uint32_t            flags;           /*! bit vector of flags                      */
    201     uint32_t            blocked;         /*! bit vector of blocking causes            */
    202     uint32_t            signals;         /*! bit vector of signals                    */
     174    volatile uint32_t   blocked;         /*! bit vector of blocking causes            */
     175    volatile uint32_t   signals;         /*! bit vector of (KILL / SUICIDE) signals   */
    203176
    204177        error_t             errno;           /*! errno value set by last system call      */
     
    212185    remote_spinlock_t * children_lock;   /*! lock protecting the children list        */
    213186
    214     xlist_entry_t       brothers_list;   /*! member of threads with same parent       */
     187    xlist_entry_t       brothers_list;   /*! list of attached threads to same parent  */
    215188
    216189        list_entry_t        sched_list;      /*! member of threads attached to same core  */
     
    273246
    274247/***************************************************************************************
    275  * This function allocates memory for an user thread descriptor in the local cluster,
     248 * This function is used by the fork() system call to create the child process main
     249 * thread. It allocates memory for an user thread descriptor in the local cluster,
    276250 * and initializes it from information contained in the calling thread descriptor.
    277  * It is used by the fork() system call to create the child process main thread.
    278  * The new thread is attached to the core with the lowest load.
    279  * It is registered in the process descriptor defined by the "process" argument.
    280  * This new thread inherits its execution context from the calling thread,
    281  * and the "loadable" field is NOT set.
    282  * The THREAD_BLOCKED_GLOBAL bit is set, and the thread must be activated to start.
     251 * The new thread is attached to the core that has the lowest load in local cluster.
     252 * It is registered in the child process descriptor defined by the <process> argument.
     253 * This new thread inherits its user stack from the parent thread, as it uses the
     254 * Copy-On-Write mechanism to get a private stack when required.
     255 * The content of the parent kernel stack is copied into the child kernel stack, as
     256 * the Copy-On-Write mechanism cannot be used for kernel segments (because kernel
     257 * uses physical addressing on some architectures).
     258 * The CPU and FPU execution contexts are created and linked to the new thread,
     259 * but the actual context copy is NOT done. The THREAD_BLOCKED_GLOBAL bit is set,
     260 * and the thread must be explicitely unblocked later to make the new thread runable.
    283261 ***************************************************************************************
    284262 * @ process      : local pointer on owner process descriptor.
     263 * @ stack_base   : user stack base address (from parent).
     264 * @ stack_size   : user stack size (from parent).
    285265 * @ new_thread   : [out] address of buffer for new thread descriptor pointer.
    286266 * @ returns 0 if success / returns ENOMEM if error.
    287267 **************************************************************************************/
    288268error_t thread_user_fork( process_t * process,
     269                          intptr_t    stack_base,
     270                          uint32_t    stack_size,
    289271                          thread_t ** new_thread );
    290272
     
    351333 * It does NOT take a lock, as this function is always called by the parent thread.
    352334 ***************************************************************************************
    353  * @ xp_parent : extended pointer on the parent thread descriptor.
    354  * @ xp_child  : extended pointer on the child thread descriptor.
    355  **************************************************************************************/
    356 void thread_child_parent_link( xptr_t  xp_parent,
    357                                xptr_t  xp_child );
     335 * @ parent_xp : extended pointer on the parent thread descriptor.
     336 * @ child_xp  : extended pointer on the child thread descriptor.
     337 **************************************************************************************/
     338void thread_child_parent_link( xptr_t  parent_xp,
     339                               xptr_t  child_xp );
    358340
    359341/***************************************************************************************
     
    361343 * of attached children threads.
    362344 ***************************************************************************************
    363  * @ xp_parent : extended pointer on the parent thread descriptor.
    364  * @ xp_child  : extended pointer on the child thread descriptor.
    365  **************************************************************************************/
    366 void thread_child_parent_unlink( xptr_t xp_parent,
    367                                  xptr_t xp_child );
     345 * @ parent_xp : extended pointer on the parent thread descriptor.
     346 * @ child_xp  : extended pointer on the child thread descriptor.
     347 **************************************************************************************/
     348void thread_child_parent_unlink( xptr_t parent_xp,
     349                                 xptr_t child_xp );
    368350
    369351/***************************************************************************************
     
    386368
    387369/***************************************************************************************
    388  * This function returns true if the calling thread is attached to its parent thread.
    389  **************************************************************************************/
    390 inline bool_t thread_is_joinable();
    391 
    392 /***************************************************************************************
    393  * This function returns true if the calling thread is not blocked.
    394  **************************************************************************************/
    395 inline bool_t thread_is_runnable();
    396 
    397 /***************************************************************************************
    398370 * This function checks if the calling thread can deschedule.
    399371 ***************************************************************************************
     
    403375
    404376/***************************************************************************************
    405  * This function implements the delayed descheduling machanism : It is called  by
     377 * This function implements the delayed descheduling mechanism : It is called  by
    406378 * all lock release functions, and calls the sched_yield() function when all locks
    407  * have beeen released and the THREAD_FLAG_SCHED flag is set.
     379 * have beeen released and the calling thread THREAD_FLAG_SCHED flag is set.
    408380 **************************************************************************************/
    409381void thread_check_sched();
    410382
    411383/***************************************************************************************
    412  * This function can be used by the calling thread to suicide.
    413  * All locks must be previously released.
    414  * The scenario depends on the attached/detached flag :
    415  * - if detached, it sets the SIG_KILL signal in the "signals" bit_vector, registers
    416  *   the BLOCKED_EXIT bit in the "blocked" bit_vector, and deschedule.
    417  * - if attached, it simply sets the BLOCKED_EXIT bit in the "blocked" bit vector
    418  *   and deschedule. The SIG_KILL signal will be set by the parent thread when
    419  *   executing the pthread_join().
     384 * This function is used by the calling thread to suicide.
     385 * All locks must be previously released. The scenario depends on the DETACHED flag.
     386 * if detached :
     387 * 1) the calling thread sets the SIG_SUICIDE bit in the "signals" bit_vector,
     388 *    registers the BLOCKED_GLOBAL bit in the "blocked" bit_vector, and deschedule.
     389 * 2) the scheduler, detecting the SIG_SUICIDE bit, remove the thread from the
     390 *    scheduler list, remove the thread from its process, and destroys the thread.
     391 * if attached :
     392 * 1) the calling thread simply sets the BLOCKED_EXIT bit in the "blocked" bit vector
     393 *    and deschedule.
     394 * 2) The SIG_KILL bit and BLOCKED_SIGNAL bits are set by the parent thread when
     395 *    executing the pthread_join(), and detecting the BLOCKED_EXIT bit.
     396 *    The scenario is a standard kill as described below.
    420397 ***************************************************************************************
    421398 * @ returns 0 if success / returns EINVAL if locks_count is not zero.
     
    424401
    425402/***************************************************************************************
     403 * This function request to kill a local target thread, with the following scenario:
     404 * 1. This function set the BLOCKED_GLOBAL bit in target thread "blocked" bit_vector,
     405 *    set the SIG_KILL bit in target thread "signals" bit_vector, and send an IPI
     406 *    to the target thread core to force scheduling.
     407 * 2. The scheduler, detecting the SIG_KILL set, removes the thread from the scheduler
     408 *    list, and reset the SIG_KILL bit to acknowledge the killer.
     409 * 3. The caller of this function, (such as the process_kill() function), must poll
     410 *    SIG_KILL bit until reset, detach the thread from its parent if the thread is
     411 *    attached, remove the thread from its process, and destroys the thread.
     412 *
     413 * NOTE: The third step must be done by the caller to allows the process_kill()
     414 *       function to parallelize the work on all schedulers in a given cluster.
     415 ***************************************************************************************
     416 * @ thread   : local pointer on the target thread.
     417 **************************************************************************************/
     418void thread_kill( thread_t * thread );
     419
     420/***************************************************************************************
    426421 * This function registers a blocking cause in the target thread "blocked" bit vector.
    427  * Warning : this function does not deschedule the calling thread.
    428  * The descheduling can be forced by a sched_yield().
    429  ***************************************************************************************
    430  * @ thread   : local pointer on target thread.
     422 * Warning : this function does not deschedule the calling thread, and the descheduling
     423 * must be explicitely forced by a sched_yield().
     424 ***************************************************************************************
     425 * @ thread   : local pointer on target thread descriptor.
    431426 * @ cause    : mask defining the cause (one hot).
    432427 **************************************************************************************/
     
    436431/***************************************************************************************
    437432 * This function resets the bit identified by the cause argument in the "blocked"
    438  * bit vector of a remote thread descriptor.
     433 * bit vector of a remote thread descriptor, using an atomic access.
    439434 * We need an extended pointer, because the client thread of an I/O operation on a
    440435 * given device is not in the same cluster as the associated device descriptor.
     
    444439 * @ thread   : extended pointer on the remote thread.
    445440 * @ cause    : mask defining the cause (one hot).
    446  **************************************************************************************/
    447 void thread_unblock( xptr_t   thread,
    448                      uint32_t cause );
    449 
    450 /***************************************************************************************
    451  * This function kills a target thread, identified by its local pointer.
    452  * It is generally called by the local process_destroy() function.
    453  * - it forces the global blocked bit in target thread descriptor.
    454  * - it set the SIG_KILL signal in target thread.
    455  * - it send an IPI_SCHED_REQUEST to the target thread core.
    456  ***************************************************************************************
    457  * @ thread   : local pointer on the target thread.
    458  * @ returns 0 if success / returns EINVAL if locks_count is not zero.
    459  **************************************************************************************/
    460 void thread_kill( thread_t * thread );
     441 * @ return non zero if the bit-vector was actually modified / return 0 otherwise
     442 **************************************************************************************/
     443uint32_t thread_unblock( xptr_t   thread,
     444                         uint32_t cause );
    461445
    462446/***************************************************************************************
  • trunk/kernel/libk/elf.c

    r406 r407  
    175175                }
    176176
     177        // get .elf file descriptor cluster and local pointer
     178        cxy_t        file_cxy = GET_CXY( file_xp );
     179        vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     180
     181        // get local pointer on .elf file mapper
     182        mapper_t * mapper_ptr = (mapper_t *)hal_remote_lpt( XPTR( file_cxy ,
     183                                                                  &file_ptr->mapper ) );
    177184                // register vseg in VMM
    178185                vseg = (vseg_t *)vmm_create_vseg( process,
     186                                          type,
    179187                                                  vbase,
    180188                                                  mem_size,
    181                                                   type );
     189                                          file_offset,
     190                                          file_size,
     191                                          XPTR( file_cxy , mapper_ptr ),
     192                                                  local_cxy ); 
    182193                if( vseg == NULL )
    183194                {
     
    187198                }
    188199
    189         // get .elf file descriptor cluster and local pointer
    190         cxy_t        file_cxy = GET_CXY( file_xp );
    191         vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
    192 
    193         // get local pointer on .elf file mapper
    194         mapper_t * mapper_ptr = (mapper_t *)hal_remote_lpt( XPTR( file_cxy ,
    195                                                                   &file_ptr->mapper ) );
    196 
    197         // initialize "file_mapper", "file_offset", "file_size" fields in vseg
    198         vseg->mapper_xp   = XPTR( file_cxy , mapper_ptr );
    199         vseg->file_offset = file_offset;
    200         vseg->file_size   = file_size;
    201 
    202200        // update reference counter in file descriptor
    203201                vfs_file_count_up( file_xp );
    204202
    205                 elf_dmsg("\n[DMSG] %s : found %s vseg / base = %x / size = %x\n"
     203                elf_dmsg("\n[DBG] %s : found %s vseg / base = %x / size = %x\n"
    206204                 "       file_size = %x / file_offset = %x / mapper_xp = %l\n",
    207205            __FUNCTION__ , vseg_type_str(vseg->type) , vseg->min , vseg->max - vseg->min ,
     
    225223        error_t      error;
    226224
    227     elf_dmsg("\n[DMSG] %s : core[%x,%d] enter for <%s>\n",
     225    elf_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s>\n",
    228226    __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pathname );
    229227
     
    233231
    234232        // open file
    235         error = vfs_open( process->vfs_cwd_xp,
     233        error = vfs_open( process,
    236234                          pathname,
    237235                          O_RDONLY,
     
    245243        }
    246244
    247     elf_dmsg("\n[DMSG] %s : open file <%s>\n", __FUNCTION__ , pathname );
     245    elf_dmsg("\n[DBG] %s : open file <%s>\n", __FUNCTION__ , pathname );
    248246
    249247        // load header in local buffer
     
    258256        }
    259257
    260         elf_dmsg("\n[DMSG] %s : loaded elf header for %s\n", __FUNCTION__ , pathname );
     258        elf_dmsg("\n[DBG] %s : loaded elf header for %s\n", __FUNCTION__ , pathname );
    261259
    262260        if( header.e_phnum == 0 )
     
    295293        }
    296294
    297         elf_dmsg("\n[DMSG] %s : segments array allocated for %s\n", __FUNCTION__ , pathname );
     295        elf_dmsg("\n[DBG] %s : segments array allocated for %s\n", __FUNCTION__ , pathname );
    298296
    299297        // load seg descriptors array to local buffer
     
    312310        }
    313311
    314         elf_dmsg("\n[DMSG] %s loaded segments descriptors for %s \n", __FUNCTION__ , pathname );
     312        elf_dmsg("\n[DBG] %s loaded segments descriptors for %s \n", __FUNCTION__ , pathname );
    315313
    316314        // register loadable segments in process VMM
     
    337335        kmem_free(&req);
    338336
    339     elf_dmsg("\n[DMSG] %s : core[%x,%d] exit for <%s> / entry_point = %x\n",
     337    elf_dmsg("\n[DBG] %s : core[%x,%d] exit for <%s> / entry_point = %x\n",
    340338    __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pathname , header.e_entry );
    341339
  • trunk/kernel/libk/remote_barrier.c

    r296 r407  
    274274        // block & deschedule the calling thread
    275275        thread_block( thread_ptr , THREAD_BLOCKED_USERSYNC );
    276         sched_yield( NULL );
     276        sched_yield();
    277277
    278278        // restore interrupts
  • trunk/kernel/libk/remote_condvar.c

    r296 r407  
    189189    // block the calling thread
    190190    thread_block( CURRENT_THREAD , THREAD_BLOCKED_USERSYNC );
    191     sched_yield( NULL );
     191    sched_yield();
    192192
    193193    // lock the mutex before return
  • trunk/kernel/libk/remote_fifo.c

    r296 r407  
    3939    uint32_t  slot;
    4040
     41    fifo->owner     = 0;
    4142        fifo->wr_id     = 0;
    4243        fifo->rd_id     = 0;
     
    4748}
    4849
    49 //////////////////////////////////////////////
    50 error_t remote_fifo_put_item( xptr_t     fifo,
    51                               uint64_t   item,
    52                               bool_t   * first )
     50/////////////////////////////////////////////////
     51error_t remote_fifo_put_item( xptr_t     fifo_xp,
     52                              uint64_t   item )
    5353{
    5454    uint32_t        wr_id;
     
    5656    uint32_t        ptw;
    5757    uint32_t        watchdog;
    58     reg_t           save_sr;
    5958    uint32_t        nslots;
    6059
    6160    // get remote cluster identifier and pointer on FIFO
    62     cxy_t           cxy = (cxy_t)GET_CXY( fifo );
    63     remote_fifo_t * ptr = (remote_fifo_t *)GET_PTR( fifo );
     61    cxy_t           fifo_cxy = (cxy_t)GET_CXY( fifo_xp );
     62    remote_fifo_t * fifo_ptr = (remote_fifo_t *)GET_PTR( fifo_xp );
    6463
    6564    // initialise watchdog for contention detection
    6665    watchdog = 0;
    6766
    68     // no descheduling during put access
    69         hal_disable_irq( &save_sr );
    70        
    71     // get write slot index and atomic increment
    72         wr_id = hal_remote_atomic_add( XPTR( cxy , &ptr->wr_id ) , 1 );
     67    // get write slot index with atomic increment
     68        wr_id = hal_remote_atomic_add( XPTR( fifo_cxy , &fifo_ptr->wr_id ) , 1 );
    7369
    74     // check fifo state
     70    // wait until allocated slot is empty in remote FIFO
     71    // max retry = CONFIG_REMOTE_FIFO_MAX_ITERATIONS 
     72    // return error if watchdog is reached
    7573    while( 1 )
    7674    {
    7775        // return error if contention detected by watchdog
    78         if( watchdog > CONFIG_REMOTE_FIFO_MAX_ITERATIONS )
    79         {
    80             // restore scheduling
    81                 hal_restore_irq( save_sr );
    82 
    83             // return error
    84             return EBUSY;
    85         }
     76        if( watchdog > CONFIG_REMOTE_FIFO_MAX_ITERATIONS )  return EBUSY;
    8677
    8778        // read remote rd_id value
    88         rd_id = hal_remote_lw( XPTR( cxy , &ptr->rd_id ) );
     79        rd_id = hal_remote_lw( XPTR( fifo_cxy , &fifo_ptr->rd_id ) );
    8980
    9081        // compute number of full slots
     
    9283        else                 nslots = (0xFFFFFFFF - rd_id) + wr_id;
    9384
    94         // exit if fifo not full
     85        // exit waiting loop as soon as fifo not full
    9586        if ( nslots < CONFIG_REMOTE_FIFO_SLOTS )  break;
    9687       
    97         // restore interrupts
    98             hal_restore_irq( save_sr );
    99 
    100         // deschedule without blocking
    101         if( thread_can_yield() ) sched_yield( NULL );
    102 
    103         // disable interrupts
    104             hal_disable_irq( &save_sr );
     88        // retry later if fifo full:
     89        // - deschedule without blocking if possible
     90        // - wait ~1000 cycles otherwise
     91        if( thread_can_yield() ) sched_yield();
     92        else                     hal_fixed_delay( 1000 );
    10593
    10694        // increment watchdog
     
    112100
    113101    // copy item to fifo
    114         hal_remote_swd( XPTR( cxy , &ptr->data[ptw] ), item );
    115 
     102        hal_remote_swd( XPTR( fifo_cxy , &fifo_ptr->data[ptw] ), item );
    116103        hal_fence();
    117104
    118105    // set the slot valid flag
    119         hal_remote_sw( XPTR( cxy , &ptr->valid[ptw] ) , 1 );
     106        hal_remote_sw( XPTR( fifo_cxy , &fifo_ptr->valid[ptw] ) , 1 );
    120107        hal_fence();
    121 
    122     // return the first RPC flag
    123     *first = ( wr_id == rd_id );
    124    
    125     // restore scheduling
    126         hal_restore_irq( save_sr );
    127108
    128109    return 0;
  • trunk/kernel/libk/remote_fifo.h

    r279 r407  
    2828#include <kernel_config.h>
    2929#include <hal_types.h>
     30#include <printk.h>
    3031#include <errno.h>
    3132#include <hal_remote.h>
    3233
    3334/************************************************************************************
    34  * This structure defines a generic, single reader, multiple writers
    35  * remote FIFO, that is used by the RPCs for inter cluster communications.
    36  * The accesses are implemented using a lock-free algorithm, as it uses a ticket
    37  * based mechanism to handle concurrent access between multiple writers.
    38  * Each FIF0 slot can contain one 64 bits integer.
    39  * In case of FIFO full, the writer deschedule without blocking, to retry later.
    40  *
    41  * WARNING : the number of slots is statically defined by the global
    42  * configuration parameter CONFIG_REMOTE_FIFO_SLOTS for all fifos. requiring
    43  * Each FIFO requires 8 + (12 * CONFIG_REMOTE_FIFO_SLOTS) bytes.
     35 * This structure defines a generic, single reader, multiple writers FIFO,
     36 * that is used for - RPC based - inter cluster communications.
     37 * Each FIF0 slot can contain one 64 bits integer (or one extended pointer).
     38 * The number of slots is defined by the CONFIG_REMOTE_FIFO_SLOTS parameter.
     39 * - The write accesses are implemented using a lock-free algorithm, as it uses
     40 *   a ticket based mechanism to handle concurrent access between multiple writers.
     41 *   In case of FIFO full, the writer deschedule without blocking, to retry later.
     42 * - The reader must take the try_lock implemented by the "owner" field, using
     43 *   an atomic_add(). The TRDID is a good owner identifier, because all
     44 *   RPC threads in a given cluster belong to the same kernel process,
     45 *   and RPC threads cannot have local index LTID = 0.
     46*
     47 * WARNING : Each FIFO requires 12 + (12 * CONFIG_REMOTE_FIFO_SLOTS) bytes.
    4448 ***********************************************************************************/
    4549
    4650typedef struct remote_fifo_s
    4751{
     52    uint32_t           owner;                            /*! owner thread trdid    */
    4853        volatile uint32_t  wr_id;                            /*! write slot index      */
    4954        volatile uint32_t  rd_id;                            /*! read  slot index      */
     
    6368/************************************************************************************
    6469 * This non blocking function tries to get one item from the local fifo.
    65  * The reader must get exclusive access before calling this function. 
     70 * The reader must get exclusive access for read before calling this function. 
    6671 * The read slot index is incremented.
    6772 ************************************************************************************
     
    7580/************************************************************************************
    7681 * This blocking function puts one item to a remote fifo identified
    77  * by an extended pointer.
    78  * This function gets a write ticket using a remote_atomic_increment on the
    79  * write slot. Then, it waits until the slot is empty, using a descheduling
    80  * policy without blocking.
     82 * by an extended pointer. It gets a write ticket on the slot to be written,
     83 * using a remote_atomic_add() on the write slot index. Then, it waits until
     84 * the slot is empty, using a descheduling policy without blocking if required.
     85 * It implements a watchdog, returning when the item has been successfully
     86 * registered, or after CONFIG_REMOTE_FIFO_MAX_ITERATIONS failures.   
    8187 ************************************************************************************
    8288 * @ fifo    : extended pointer to the fifo in remote cluster.
    8389 * @ item    : item to be stored.
    84  * @ first   : [out] true if first item registered in remote fifo.
    8590 * @ return  0 on success / EBUSY if a contention has been detected.
    8691 ***********************************************************************************/
    8792error_t remote_fifo_put_item( xptr_t     fifo,
    88                               uint64_t   item,
    89                               bool_t   * first );
     93                              uint64_t   item );
    9094
    9195/************************************************************************************
  • trunk/kernel/libk/remote_mutex.c

    r296 r407  
    208208        // block & deschedule the calling thread   
    209209        thread_block( thread_ptr , THREAD_BLOCKED_USERSYNC );
    210         sched_yield( NULL );
     210        sched_yield();
    211211
    212212        // restore interrupts
  • trunk/kernel/libk/remote_sem.c

    r296 r407  
    219219        // block and deschedule
    220220        thread_block( this , THREAD_BLOCKED_SEM ); 
    221         sched_yield( NULL );
     221        sched_yield();
    222222        }
    223223}  // end remote_sem_wait()
  • trunk/kernel/libk/remote_spinlock.c

    r337 r407  
    179179                {
    180180                        hal_restore_irq( mode );
    181                         if( thread_can_yield() ) sched_yield( NULL );
     181                        if( thread_can_yield() ) sched_yield();
    182182                        hal_disable_irq( &mode );
    183183                        continue;
  • trunk/kernel/libk/spinlock.c

    r337 r407  
    111111        {
    112112            hal_restore_irq( mode );
    113             if( thread_can_yield() ) sched_yield( NULL );
     113            if( thread_can_yield() ) sched_yield();
    114114            hal_disable_irq( &mode );
    115115            continue;
  • trunk/kernel/mm/kcm.c

    r406 r407  
    4747                             kcm_page_t * kcm_page )
    4848{
    49         kcm_dmsg("\n[DMSG] %s : enters for %s / page %x / count = %d / active = %d\n",
     49        kcm_dmsg("\n[DBG] %s : enters for %s / page %x / count = %d / active = %d\n",
    5050                 __FUNCTION__ , kmem_type_str( kcm->type ) ,
    5151                 (intptr_t)kcm_page , kcm_page->count , kcm_page->active );
     
    8080                     + (index * kcm->block_size) );
    8181
    82         kcm_dmsg("\n[DMSG] %s : allocated one block  %s / ptr = %p / page = %x / count = %d\n",
     82        kcm_dmsg("\n[DBG] %s : allocated one block  %s / ptr = %p / page = %x / count = %d\n",
    8383                 __FUNCTION__ , kmem_type_str( kcm->type ) , ptr ,
    8484                 (intptr_t)kcm_page , kcm_page->count );
     
    231231        kcm->blocks_nr = blocks_nr;
    232232
    233         kcm_dmsg("\n[DMSG] %s : KCM %s initialised / block_size = %d / blocks_nr = %d\n",
     233        kcm_dmsg("\n[DBG] %s : KCM %s initialised / block_size = %d / blocks_nr = %d\n",
    234234                 __FUNCTION__ , kmem_type_str( type ) , kcm->block_size , kcm->blocks_nr );
    235235}
     
    301301                kcm_page->active = 1;
    302302
    303                 kcm_dmsg("\n[DMSG] %s : enters for type %s at cycle %d / new page = %x / count = %d\n",
     303                kcm_dmsg("\n[DBG] %s : enters for type %s at cycle %d / new page = %x / count = %d\n",
    304304                         __FUNCTION__ , kmem_type_str( kcm->type ) , hal_get_cycles() ,
    305305                         (intptr_t)kcm_page , kcm_page->count );
     
    311311                kcm_page = (kcm_page_t *)LIST_FIRST( &kcm->active_root , kcm_page_t , list );
    312312
    313                 kcm_dmsg("\n[DMSG] %s : enters for type %s at cycle %d / page = %x / count = %d\n",
     313                kcm_dmsg("\n[DBG] %s : enters for type %s at cycle %d / page = %x / count = %d\n",
    314314                         __FUNCTION__ , kmem_type_str( kcm->type ) , hal_get_cycles() ,
    315315                         (intptr_t)kcm_page , kcm_page->count );
  • trunk/kernel/mm/kmem.c

    r406 r407  
    145145        assert( ((type > 1) && (type < KMEM_TYPES_NR) ) , __FUNCTION__ , "illegal KCM type" );
    146146
    147         kmem_dmsg("\n[DMSG] %s : enters / KCM type %s missing in cluster %x\n",
     147        kmem_dmsg("\n[DBG] %s : enters / KCM type %s missing in cluster %x\n",
    148148                  __FUNCTION__ , kmem_type_str( type ) , local_cxy );
    149149
     
    169169        hal_fence();
    170170
    171         kmem_dmsg("\n[DMSG] %s : exit / KCM type %s created in cluster %x\n",
     171        kmem_dmsg("\n[DBG] %s : exit / KCM type %s created in cluster %x\n",
    172172                  __FUNCTION__ , kmem_type_str( type ) , local_cxy );
    173173
     
    192192        assert( (type < KMEM_TYPES_NR) , __FUNCTION__ , "illegal KMEM request type" );
    193193
    194         kmem_dmsg("\n[DMSG] %s : enters in cluster %x for type %s\n",
     194        kmem_dmsg("\n[DBG] %s : enters in cluster %x for type %s\n",
    195195                      __FUNCTION__ , local_cxy , kmem_type_str( type ) );
    196196
     
    210210                if( flags & AF_ZERO ) page_zero( (page_t *)ptr );
    211211
    212                 kmem_dmsg("\n[DMSG] %s : exit in cluster %x for type %s / page = %x / base = %x\n",
     212                kmem_dmsg("\n[DBG] %s : exit in cluster %x for type %s / page = %x / base = %x\n",
    213213                          __FUNCTION__, local_cxy , kmem_type_str( type ) ,
    214214                          (intptr_t)ptr , (intptr_t)ppm_page2base( ptr ) );
     
    228228                if( flags & AF_ZERO ) memset( ptr , 0 , size );
    229229
    230                 kmem_dmsg("\n[DMSG] %s : exit in cluster %x for type %s / base = %x / size = %d\n",
     230                kmem_dmsg("\n[DBG] %s : exit in cluster %x for type %s / base = %x / size = %d\n",
    231231                          __FUNCTION__, local_cxy , kmem_type_str( type ) ,
    232232                          (intptr_t)ptr , req->size );
     
    255255                if( flags & AF_ZERO ) memset( ptr , 0 , kmem_type_size( type ) );
    256256
    257                 kmem_dmsg("\n[DMSG] %s : exit in cluster %x for type %s / base = %x / size = %d\n",
     257                kmem_dmsg("\n[DBG] %s : exit in cluster %x for type %s / base = %x / size = %d\n",
    258258                          __FUNCTION__, local_cxy , kmem_type_str( type ) ,
    259259                          (intptr_t)ptr , kmem_type_size( type ) );
  • trunk/kernel/mm/mapper.c

    r406 r407  
    143143    error_t       error;
    144144
    145     mapper_dmsg("\n[DMSG] %s : enters for page %d / mapper %x\n",
    146                 __FUNCTION__ , index , mapper );
     145mapper_dmsg("\n[DBG] %s : core[%x,%d] enters for page %d / mapper %x\n",
     146__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , index , mapper );
    147147
    148148    thread_t * this = CURRENT_THREAD;
     
    170170        if ( page == NULL )   // missing page => create it and load it from file system
    171171        {
    172             mapper_dmsg("\n[DMSG] %s : missing page => load from device\n", __FUNCTION__ );
     172
     173mapper_dmsg("\n[DBG] %s : core[%x,%d] missing page => load from device\n",
     174__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
    173175
    174176            // allocate one page from PPM
     
    188190            // initialize the page descriptor
    189191            page_init( page );
    190             page_set_flag( page , PG_INIT );
    191             page_set_flag( page , PG_INLOAD );
     192            page_set_flag( page , PG_INIT | PG_INLOAD );
    192193            page_refcount_up( page );
    193194            page->mapper = mapper;
     
    215216            error = vfs_mapper_move_page( page,
    216217                                          true );   // to mapper
    217 
    218218            if( error )
    219219            {
     
    231231            page_clear_flag( page , PG_INLOAD );
    232232
     233mapper_dmsg("\n[DBG] %s : missing page loaded / ppn = %x\n",
     234__FUNCTION__ , ppm_page2ppn(XPTR(local_cxy,page)) );
     235
    233236        }
    234237        else if( page_is_flag( page , PG_INLOAD ) )   // page is loaded by another thread
     
    244247
    245248                // deschedule
    246                 sched_yield( NULL );
     249                sched_yield();
    247250            }
    248251        }
     
    254257    }
    255258
    256     mapper_dmsg("\n[DMSG] %s : exit for page %d / mapper %x / page_desc = %x\n",
    257                 __FUNCTION__ , index , mapper , page );
     259mapper_dmsg("\n[DBG] %s : exit for page %d / mapper %x / page_desc = %x\n",
     260__FUNCTION__ , index , mapper , page );
    258261
    259262    return page;
     
    310313    uint8_t  * buf_ptr;        // current buffer  address
    311314
    312     mapper_dmsg("\n[DMSG] %s : enters / to_buf = %d / buffer = %x\n",
     315    mapper_dmsg("\n[DBG] %s : enters / to_buf = %d / buffer = %x\n",
    313316                __FUNCTION__ , to_buffer , buffer );
    314317
     
    336339        else                       page_count = CONFIG_PPM_PAGE_SIZE;
    337340
    338         mapper_dmsg("\n[DMSG] %s : index = %d / offset = %d / count = %d\n",
     341        mapper_dmsg("\n[DBG] %s : index = %d / offset = %d / count = %d\n",
    339342                    __FUNCTION__ , index , page_offset , page_count );
    340343
     
    351354        buf_ptr = (uint8_t *)buffer + done;
    352355
    353         mapper_dmsg("\n[DMSG] %s : index = %d / buf_ptr = %x / map_ptr = %x\n",
     356        mapper_dmsg("\n[DBG] %s : index = %d / buf_ptr = %x / map_ptr = %x\n",
    354357                    __FUNCTION__ , index , buf_ptr , map_ptr );
    355358
     
    368371    }
    369372
    370     mapper_dmsg("\n[DMSG] %s : exit for buffer %x\n",
     373    mapper_dmsg("\n[DBG] %s : exit for buffer %x\n",
    371374                __FUNCTION__, buffer );
    372375
     
    397400    uint8_t * buffer_ptr = (uint8_t *)GET_PTR( buffer_xp );
    398401
    399     mapper_dmsg("\n[DMSG] %s : to_buf = %d / buf_cxy = %x / buf_ptr = %x / size = %x\n",
    400     __FUNCTION__ , to_buffer , buffer_cxy , buffer_ptr , size );
     402mapper_dmsg("\n[DBG] %s : core[%x,%d] / to_buf = %d / buf_cxy = %x / buf_ptr = %x / size = %x\n",
     403__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, to_buffer, buffer_cxy, buffer_ptr, size );
    401404
    402405    // compute offsets of first and last bytes in file
     
    408411    uint32_t last  = max_byte >> CONFIG_PPM_PAGE_SHIFT;
    409412
    410     mapper_dmsg("\n[DMSG] %s : first_page = %d / last_page = %d\n",
    411     __FUNCTION__ , first , last );
     413mapper_dmsg("\n[DBG] %s : core[%x,%d] / first_page = %d / last_page = %d\n",
     414__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, first, last );
    412415
    413416    // compute source and destination clusters
     
    438441        else                       page_count = CONFIG_PPM_PAGE_SIZE;
    439442
    440         mapper_dmsg("\n[DMSG] %s : page_index = %d / offset = %d / bytes = %d\n",
    441                     __FUNCTION__ , index , page_offset , page_count );
     443mapper_dmsg("\n[DBG] %s : core[%x;%d] / page_index = %d / offset = %d / bytes = %d\n",
     444__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, index, page_offset, page_count );
    442445
    443446        // get page descriptor
     
    470473    }
    471474
    472     mapper_dmsg("\n[DMSG] %s : exit / buf_cxy = %x / buf_ptr = %x / size = %x\n",
    473     __FUNCTION__ , buffer_cxy , buffer_ptr , size );
     475mapper_dmsg("\n[DBG] %s : core_cxy[%x,%d] / exit / buf_cxy = %x / buf_ptr = %x / size = %x\n",
     476__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, buffer_cxy, buffer_ptr, size );
    474477
    475478    return 0;
  • trunk/kernel/mm/mapper.h

    r315 r407  
    131131 * @ to_buffer    : mapper -> buffer if true / buffer -> mapper if false.
    132132 * @ file_offset  : first byte to move in file.
    133  * @ buffer       : user space pointer on user buffer.
     133 * @ u_buf        : user space pointer on user buffer.
    134134 * @ size         : number of bytes to move.
    135135 * returns O if success / returns EINVAL if error.
     
    138138                          bool_t     to_buffer,
    139139                          uint32_t   file_offset,
    140                           void     * buffer,
     140                          void     * u_buf,
    141141                          uint32_t   size );
    142142
  • trunk/kernel/mm/page.c

    r315 r407  
    4646        page->mapper   = NULL;
    4747        page->index    = 0;
    48         page->fork_nr  = 0;
    4948        page->refcount = 0;
    5049
     
    181180                // deschedule the calling thread
    182181                thread_block( thread , THREAD_BLOCKED_PAGE );
    183                 sched_yield( NULL );
     182                sched_yield();
    184183        }
    185184        else                                    // page is not locked
  • trunk/kernel/mm/page.h

    r315 r407  
    6767    xlist_entry_t     wait_root;      /*! root of list of waiting threads      (16) */
    6868        uint32_t          refcount;       /*! reference counter                    (4)  */
    69         uint32_t          fork_nr;        /*! number of forked processes           (4)  */
     69        uint32_t          reserved;       /*! UNUSED                               (4)  */
    7070        spinlock_t        lock;           /*! only used to set the PG_LOCKED flag  (16) */
    7171}
  • trunk/kernel/mm/ppm.c

    r406 r407  
    154154        page_t   * pages_tbl   = ppm->pages_tbl;
    155155
    156         assert( !page_is_flag( page , PG_FREE ) , __FUNCTION__ , "page already freed" );
    157         assert( !page_is_flag( page , PG_RESERVED ) , __FUNCTION__ , "freeing reserved page" );
     156        assert( !page_is_flag( page , PG_FREE ) , __FUNCTION__ ,
     157    "page already released : ppn = %x\n" , ppm_page2ppn(XPTR(local_cxy,page)) );
     158
     159        assert( !page_is_flag( page , PG_RESERVED ) , __FUNCTION__ ,
     160    "reserved page : ppn = %x\n" , ppm_page2ppn(XPTR(local_cxy,page)) );
    158161
    159162        // update released page descriptor flags
     
    201204        ppm_t    * ppm = &LOCAL_CLUSTER->ppm;
    202205
    203         assert( (order < CONFIG_PPM_MAX_ORDER) , __FUNCTION__ , "illegal order argument" );
     206        assert( (order < CONFIG_PPM_MAX_ORDER) , __FUNCTION__ ,
     207    "illegal order argument = %x\n" , order );
    204208
    205209        page_t * block = NULL; 
    206210
    207         ppm_dmsg("\n[DMSG] %s : enters / order = %d\n",
     211        ppm_dmsg("\n[DBG] %s : enters / order = %d\n",
    208212                 __FUNCTION__ , order );
    209213
     
    256260        spinlock_unlock( &ppm->free_lock );
    257261
    258         ppm_dmsg("\n[DMSG] %s : base = %x / order = %d\n",
     262        ppm_dmsg("\n[DBG] %s : base = %x / order = %d\n",
    259263                 __FUNCTION__ , (uint32_t)ppm_page2base( block ) , order );
    260264
     
    289293
    290294        printk("\n***  PPM in cluster %x : %d pages / &pages_tbl = %x / vaddr_base = %x ***\n",
    291                local_cxy , ppm->pages_nr , (intptr_t)ppm->pages_tbl , (intptr_t)ppm->vaddr_base );
     295    local_cxy , ppm->pages_nr , (intptr_t)ppm->pages_tbl , (intptr_t)ppm->vaddr_base );
    292296
    293297        for( order = 0 ; order < CONFIG_PPM_MAX_ORDER ; order++ )
     
    316320        page_t       * page;
    317321
    318         for(order=0; order < CONFIG_PPM_MAX_ORDER; order++)
     322        for( order=0 ; order < CONFIG_PPM_MAX_ORDER ; order++ )
    319323        {
    320324                if( list_is_empty( &ppm->free_pages_root[order] ) ) continue;
  • trunk/kernel/mm/ppm.h

    r315 r407  
    127127
    128128/*****************************************************************************************
    129  * Get extended pointer on page base from Global PPN.
     129 * Get extended pointer on page base from global PPN.
    130130 *****************************************************************************************
    131131 * @ ppn    : global physical page number.
  • trunk/kernel/mm/vmm.c

    r406 r407  
    5858    vseg_t  * vseg_args;
    5959    vseg_t  * vseg_envs;
    60     vseg_t  * vseg_heap;
    6160    intptr_t  base;
    6261    intptr_t  size;
    6362
    64     vmm_dmsg("\n[DMSG] %s : enter for process %x\n", __FUNCTION__ , process->pid );
     63vmm_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x\n",
     64__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , process->pid );
    6565
    6666    // get pointer on VMM
    6767    vmm_t   * vmm = &process->vmm;
     68
     69    // initialize local list of vsegs
     70    vmm->vsegs_nr = 0;
     71        list_root_init( &vmm->vsegs_root );
     72        rwlock_init( &vmm->vsegs_lock );
    6873
    6974    assert( ((CONFIG_VMM_KENTRY_SIZE + CONFIG_VMM_ARGS_SIZE + CONFIG_VMM_ENVS_SIZE)
     
    7782             "STACK zone too small\n");
    7883
    79     // initialize the rwlock protecting the vsegs list
    80         rwlock_init( &vmm->vsegs_lock );
    81 
    82     // initialize local list of vsegs and radix-tree
    83     vmm->vsegs_nr = 0;
    84         list_root_init( &vmm->vsegs_root );
    85 
    8684    // register kentry vseg in VMM
    8785    base = CONFIG_VMM_KENTRY_BASE << CONFIG_PPM_PAGE_SHIFT;
    8886    size = CONFIG_VMM_KENTRY_SIZE << CONFIG_PPM_PAGE_SHIFT;
    8987
    90     vseg_kentry = vmm_create_vseg( process , base , size , VSEG_TYPE_CODE );
     88    vseg_kentry = vmm_create_vseg( process,
     89                                   VSEG_TYPE_CODE,
     90                                   base,
     91                                   size,
     92                                   0,             // file_offset unused
     93                                   0,             // file_size unused
     94                                   XPTR_NULL,     // mapper_xp unused
     95                                   local_cxy );
    9196
    9297    assert( (vseg_kentry != NULL) , __FUNCTION__ , "cannot register kentry vseg\n" );
     
    99104    size = CONFIG_VMM_ARGS_SIZE << CONFIG_PPM_PAGE_SHIFT;
    100105
    101     vseg_args = vmm_create_vseg( process , base , size , VSEG_TYPE_DATA );
    102 
    103     assert( (vseg_args != NULL) , __FUNCTION__ , "cannot register args vseg\n" );
     106    vseg_args = vmm_create_vseg( process,
     107                                 VSEG_TYPE_DATA,
     108                                 base,
     109                                 size,
     110                                 0,             // file_offset unused
     111                                 0,             // file_size unused
     112                                 XPTR_NULL,     // mapper_xp unused
     113                                 local_cxy );
     114
     115    assert( (vseg_args != NULL) , __FUNCTION__ , "cannot create args vseg\n" );
    104116
    105117    vmm->args_vpn_base = base;
     
    111123    size = CONFIG_VMM_ENVS_SIZE << CONFIG_PPM_PAGE_SHIFT;
    112124
    113     vseg_envs = vmm_create_vseg( process , base , size , VSEG_TYPE_DATA );
    114 
    115     assert( (vseg_envs != NULL) , __FUNCTION__ , "cannot register envs vseg\n" );
     125    vseg_envs = vmm_create_vseg( process,
     126                                 VSEG_TYPE_DATA,
     127                                 base,
     128                                 size,
     129                                 0,             // file_offset unused
     130                                 0,             // file_size unused
     131                                 XPTR_NULL,     // mapper_xp unused
     132                                 local_cxy );
     133
     134    assert( (vseg_envs != NULL) , __FUNCTION__ , "cannot create envs vseg\n" );
    116135
    117136    vmm->envs_vpn_base = base;
    118 
    119     // register the heap vseg in VMM
    120     base = CONFIG_VMM_HEAP_BASE << CONFIG_PPM_PAGE_SHIFT;
    121     size = (CONFIG_VMM_MMAP_BASE-CONFIG_VMM_HEAP_BASE) << CONFIG_PPM_PAGE_SHIFT;
    122 
    123     vseg_heap = vmm_create_vseg( process , base , size , VSEG_TYPE_HEAP );
    124 
    125     assert( (vseg_heap != NULL) , __FUNCTION__ , "cannot register heap vseg\n" );
    126 
    127     vmm->heap_vpn_base = base;
    128137
    129138    // initialize generic page table
     
    137146
    138147    // initialize MMAP allocator
    139     vmm->mmap_mgr.vpn_base        = CONFIG_VMM_MMAP_BASE;
    140     vmm->mmap_mgr.vpn_size        = CONFIG_VMM_STACK_BASE - CONFIG_VMM_MMAP_BASE;
    141     vmm->mmap_mgr.first_free_vpn  = CONFIG_VMM_MMAP_BASE;
     148    vmm->mmap_mgr.vpn_base        = CONFIG_VMM_HEAP_BASE;
     149    vmm->mmap_mgr.vpn_size        = CONFIG_VMM_STACK_BASE - CONFIG_VMM_HEAP_BASE;
     150    vmm->mmap_mgr.first_free_vpn  = CONFIG_VMM_HEAP_BASE;
    142151    uint32_t i;
    143152    for( i = 0 ; i < 32 ; i++ ) list_root_init( &vmm->mmap_mgr.zombi_list[i] );
     
    150159    hal_fence();
    151160
    152     vmm_dmsg("\n[DMSG] %s : exit for process %x / entry_point = %x\n",
    153     __FUNCTION__ , process->pid , process->vmm.entry_point );
     161vmm_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x / entry_point = %x\n",
     162__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid ,
     163process->pid , process->vmm.entry_point );
    154164
    155165}  // end vmm_init()
     166
     167//////////////////////////////////////
     168void vmm_display( process_t * process,
     169                  bool_t      mapping )
     170{
     171    vmm_t * vmm = &process->vmm;
     172    gpt_t * gpt = &vmm->gpt;
     173
     174    printk("\n***** VSL and GPT for process %x\n\n",
     175    process->pid );
     176
     177    // get lock protecting the vseg list
     178    rwlock_rd_lock( &vmm->vsegs_lock );
     179
     180    // scan the list of vsegs
     181    list_entry_t * iter;
     182    vseg_t       * vseg;
     183    LIST_FOREACH( &vmm->vsegs_root , iter )
     184    {
     185        vseg = LIST_ELEMENT( iter , vseg_t , list );
     186        printk(" - %s : base = %X / size = %X / npages = %d\n",
     187        vseg_type_str( vseg->type ) , vseg->min , vseg->max - vseg->min , vseg->vpn_size );
     188
     189        if( mapping )
     190        {
     191            vpn_t    vpn;
     192            ppn_t    ppn;
     193            uint32_t attr;
     194            vpn_t    base = vseg->vpn_base;
     195            vpn_t    size = vseg->vpn_size;
     196            for( vpn = base ; vpn < (base+size) ; vpn++ )
     197            {
     198                hal_gpt_get_pte( gpt , vpn , &attr , &ppn );
     199                if( attr & GPT_MAPPED )
     200                {
     201                    printk("    . vpn = %X / attr = %X / ppn = %X\n", vpn , attr , ppn );
     202                }
     203            }
     204        }
     205    }
     206
     207    // release the lock
     208    rwlock_rd_unlock( &vmm->vsegs_lock );
     209}
    156210
    157211//////////////////////////////////////////
     
    170224    rwlock_init( &dst_vmm->vsegs_lock );
    171225
    172     // initialize the dst_vmm vsegs list and the radix tree
     226    // initialize the dst_vmm vsegs list
    173227    dst_vmm->vsegs_nr = 0;
    174228    list_root_init( &dst_vmm->vsegs_root );
    175229
    176     // loop on src_vmm list of vsegs to create
    177     // and register vsegs copies in dst_vmm
     230    // initialize generic page table
     231    error = hal_gpt_create( &dst_vmm->gpt );
     232
     233    if( error )
     234    {
     235        printk("\n[ERROR] in %s : cannot initialize page table\n", __FUNCTION__ );
     236        return ENOMEM;
     237    }
     238
     239    // loop on SRC VSL to register vsegs copies in DST VSL
     240    // and copy valid PTEs from SRC GPT to DST GPT
    178241    list_entry_t * iter;
    179242    vseg_t       * src_vseg;
     
    201264        vseg_init_from_ref( dst_vseg , XPTR( local_cxy , src_vseg ) );
    202265
    203         // register dst_vseg in dst_vmm
     266        // register dst_vseg in DST VSL
    204267        vseg_attach( dst_vmm , dst_vseg );
     268
     269        // copy SRC GPT to DST GPT / set COW for all writable vsegs, but the FILE type
     270        bool_t cow = (src_vseg->type != VSEG_TYPE_FILE) && (src_vseg->flags & VSEG_WRITE);
     271        error = hal_gpt_copy( &dst_vmm->gpt,
     272                              &src_vmm->gpt,
     273                              src_vseg->vpn_base,
     274                              src_vseg->vpn_size,
     275                              cow );
     276        if( error )
     277        {
     278            printk("\n[ERROR] in %s : cannot copy page GPT\n", __FUNCTION__ );
     279            hal_gpt_destroy( &dst_vmm->gpt );
     280            return ENOMEM;
     281        }
    205282    }
    206283
    207284    // release the src_vmm vsegs_lock
    208285    rwlock_wr_unlock( &src_vmm->vsegs_lock );
    209 
    210     // initialize generic page table
    211     error = hal_gpt_create( &dst_vmm->gpt );
    212 
    213     if( error )
    214     {
    215         printk("\n[ERROR] in %s : cannot initialize page table\n", __FUNCTION__ );
    216         return ENOMEM;
    217     }
    218286
    219287    // initialize STACK allocator
     
    222290
    223291    // initialize MMAP allocator
    224     dst_vmm->mmap_mgr.vpn_base        = CONFIG_VMM_MMAP_BASE;
    225     dst_vmm->mmap_mgr.vpn_size        = CONFIG_VMM_STACK_BASE - CONFIG_VMM_MMAP_BASE;
    226     dst_vmm->mmap_mgr.first_free_vpn  = CONFIG_VMM_MMAP_BASE;
     292    dst_vmm->mmap_mgr.vpn_base        = CONFIG_VMM_HEAP_BASE;
     293    dst_vmm->mmap_mgr.vpn_size        = CONFIG_VMM_STACK_BASE - CONFIG_VMM_HEAP_BASE;
     294    dst_vmm->mmap_mgr.first_free_vpn  = CONFIG_VMM_HEAP_BASE;
    227295    uint32_t i;
    228296    for( i = 0 ; i < 32 ; i++ ) list_root_init( &dst_vmm->mmap_mgr.zombi_list[i] );
     
    242310
    243311    dst_vmm->entry_point   = src_vmm->entry_point;
    244 
    245     // HEAP TODO : new heap for child ???
    246     dst_vmm->heap_vseg     = src_vmm->heap_vseg;
    247 
    248     // initialize generic page table
    249     error = hal_gpt_create( &dst_vmm->gpt );
    250 
    251     if( error )
    252     {
    253         printk("\n[ERROR] in %s : cannot initialize page table\n", __FUNCTION__ );
    254         return ENOMEM;
    255     }
    256 
    257     // copy GPT content from src_vmm to dst_vmm, activating "Copy-On-Write"
    258     // TODO register Copy-On_Write in page descriptors
    259     bool_t cow = true;
    260     hal_gpt_copy( &dst_vmm->gpt , &src_vmm->gpt , cow );
    261312
    262313    hal_fence();
     
    431482}  // end vmm_mmap_alloc()
    432483
    433 //////////////////////////////////////////////
    434 vseg_t * vmm_create_vseg( process_t * process,
    435                           intptr_t    base,
    436                               intptr_t    size,
    437                               uint32_t    type )
     484////////////////////////////////////////////////
     485vseg_t * vmm_create_vseg( process_t   * process,
     486                              vseg_type_t   type,
     487                          intptr_t      base,
     488                              uint32_t      size,
     489                          uint32_t      file_offset,
     490                          uint32_t      file_size,
     491                          xptr_t        mapper_xp,
     492                          cxy_t         cxy )
    438493{
    439494    vseg_t     * vseg;          // created vseg pointer
     
    442497        error_t      error;
    443498
    444     // get pointer on VMM
    445         vmm_t * vmm = &process->vmm;
    446 
    447         vmm_dmsg("\n[DMSG] %s : enter for process %x / base = %x / size = %x / type = %s\n",
    448                      __FUNCTION__ , process->pid , base , size , vseg_type_str(type) );
     499vmm_dmsg("\n[DBG] %s : core[%x,%d] enters / process %x / base %x / size %x / %s / cxy = %x\n",
     500__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid ,
     501process->pid , base , size , vseg_type_str(type) , cxy );
     502
     503    // get pointer on VMM
     504        vmm_t * vmm    = &process->vmm;
    449505
    450506    // compute base, size, vpn_base, vpn_size, depending on vseg type
    451     // we use the VMM specific allocators for STACK and MMAP vsegs
     507    // we use the VMM specific allocators for "stack", "file", "anon", & "remote" vsegs
    452508    if( type == VSEG_TYPE_STACK )
    453509    {
     
    456512        if( error )
    457513        {
    458             printk("\n[ERROR] in %s : no vspace for stack vseg / process %x in cluster %x\n",
    459                    __FUNCTION__ , process->pid , local_cxy );
     514            printk("\n[ERROR] in %s : no space for stack vseg / process %x in cluster %x\n",
     515            __FUNCTION__ , process->pid , local_cxy );
    460516            return NULL;
    461517        }
     
    498554        printk("\n[ERROR] in %s for process %x : new vseg [vpn_base = %x / vpn_size = %x]\n"
    499555               "  overlap existing vseg [vpn_base = %x / vpn_size = %x]\n",
    500                __FUNCTION__ , process->pid, vpn_base, vpn_size,
    501                vseg->vpn_base, vseg->vpn_size );
     556        __FUNCTION__ , process->pid, vpn_base, vpn_size, vseg->vpn_base, vseg->vpn_size );
    502557        return NULL;
    503558    }
     
    508563        {
    509564            printk("\n[ERROR] in %s for process %x : cannot allocate memory for vseg\n",
    510              __FUNCTION__ , process->pid );
     565        __FUNCTION__ , process->pid );
    511566        return NULL;
    512567        }
    513568
    514569    // initialize vseg descriptor
    515         vseg_init( vseg , base, size , vpn_base , vpn_size , type , local_cxy );
    516 
    517     // update "heap_vseg" in VMM
    518         if( type == VSEG_TYPE_HEAP ) process->vmm.heap_vseg = vseg;
     570        vseg_init( vseg,
     571               type,
     572               base,
     573               size,
     574               vpn_base,
     575               vpn_size,
     576               file_offset,
     577               file_size,
     578               mapper_xp,
     579               cxy );
    519580
    520581    // attach vseg to vmm
     
    523584        rwlock_wr_unlock( &vmm->vsegs_lock );
    524585
    525         vmm_dmsg("\n[DMSG] %s : exit for process %x / vseg [%x, %x] registered\n",
    526                      __FUNCTION__ , process->pid , vseg->min , vseg->max );
     586vmm_dmsg("\n[DBG] %s : core[%x,%d] exit / process %x / base %x / size %x / type %s\n",
     587__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid ,
     588process->pid , base , size , vseg_type_str(type) );
    527589
    528590        return vseg;
     
    579641        vseg_free( vseg );
    580642    }
    581 }
     643}  // end vmm_remove_vseg()
    582644
    583645//////////////////////////////////////////////
     
    655717}
    656718
    657 ///////////////////////////////////////////////////////////////////////////////////////
     719//////////////////////////////////////////////////////////////////////////////////////////
    658720// This low-level static function is called by the vmm_get_vseg() and vmm_resize_vseg()
    659721// functions.  It scan the list of registered vsegs to find the unique vseg containing
    660722// a given virtual address.
    661 ///////////////////////////////////////////////////////////////////////////////////////
     723//////////////////////////////////////////////////////////////////////////////////////////
    662724// @ vmm     : pointer on the process VMM.
    663725// @ vaddr   : virtual address.
    664726// @ return vseg pointer if success / return NULL if not found.
    665 ///////////////////////////////////////////////////////////////////////////////////////
     727//////////////////////////////////////////////////////////////////////////////////////////
    666728static vseg_t * vseg_from_vaddr( vmm_t    * vmm,
    667729                                 intptr_t   vaddr )
     
    755817
    756818        // create new vseg
    757         new = vmm_create_vseg( process , addr_min , (vseg->max - addr_max) , vseg->type );
     819        new = vmm_create_vseg( process,
     820                               vseg->type,
     821                               addr_min,
     822                               (vseg->max - addr_max),
     823                               vseg->file_offset,
     824                               vseg->file_size,
     825                               vseg->mapper_xp,
     826                               vseg->cxy );
     827
    758828        if( new == NULL ) error = EINVAL;
    759829        else              error = 0;
     
    814884}  // end vmm_get_vseg()
    815885
     886//////////////////////////////////////////////////////////////////////////////////////
     887// This static function compute the target cluster to allocate a physical page
     888// for a given <vpn> in a given <vseg>, allocates the page (with an RPC if required)
     889// and returns an extended pointer on the allocated page descriptor.
     890// The vseg cannot have the FILE type.
     891//////////////////////////////////////////////////////////////////////////////////////
     892static xptr_t vmm_page_allocate( vseg_t * vseg,
     893                                 vpn_t    vpn )
     894{
     895    // compute target cluster
     896    page_t     * page_ptr;
     897    cxy_t        page_cxy;
     898    kmem_req_t   req;
     899
     900    uint32_t     type  = vseg->type;
     901    uint32_t     flags = vseg->flags;
     902
     903    assert( ( type != VSEG_TYPE_FILE ) , __FUNCTION__ , "illegal vseg type\n" );
     904
     905    if( flags & VSEG_DISTRIB )    // distributed => cxy depends on vpn LSB
     906    {
     907        uint32_t x_size  = LOCAL_CLUSTER->x_size;
     908        uint32_t y_size  = LOCAL_CLUSTER->y_size;
     909        uint32_t y_width = LOCAL_CLUSTER->y_width;
     910        uint32_t index   = vpn & ((x_size * y_size) - 1);
     911        uint32_t x       = index / y_size;
     912        uint32_t y       = index % y_size;
     913        page_cxy         = (x<<y_width) + y;
     914    }
     915    else                          // other cases => cxy specified in vseg
     916    {
     917        page_cxy         = vseg->cxy;
     918    }
     919
     920    // allocate a physical page from target cluster
     921    if( page_cxy == local_cxy )  // target cluster is the local cluster
     922    {
     923        req.type  = KMEM_PAGE;
     924        req.size  = 0;
     925        req.flags = AF_NONE;
     926        page_ptr  = (page_t *)kmem_alloc( &req );
     927    }
     928    else                           // target cluster is not the local cluster
     929    {
     930        rpc_pmem_get_pages_client( page_cxy , 0 , &page_ptr );
     931    }
     932
     933    if( page_ptr == NULL ) return XPTR_NULL;
     934    else                   return XPTR( page_cxy , page_ptr );
     935
     936}  // end vmm_page_allocate() 
     937
    816938////////////////////////////////////////
    817939error_t vmm_get_one_ppn( vseg_t * vseg,
     
    820942{
    821943    error_t    error;
    822     cxy_t      page_cxy;          // physical page cluster
     944    xptr_t     page_xp;           // extended pointer on physical page descriptor
    823945    page_t   * page_ptr;          // local pointer on physical page descriptor
    824946    uint32_t   index;             // missing page index in vseg mapper
     
    828950    index     = vpn - vseg->vpn_base;
    829951
    830     vmm_dmsg("\n[DMSG] %s : core[%x,%d] enter for vpn = %x / type = %s / index = %d\n",
    831     __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn, vseg_type_str(type), index );
     952vmm_dmsg("\n[DBG] %s : core[%x,%d] enter for vpn = %x / type = %s / index = %d\n",
     953__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn, vseg_type_str(type), index );
    832954
    833955    // FILE type : get the physical page from the file mapper
     
    835957    {
    836958        // get extended pointer on mapper
    837         xptr_t     mapper_xp = vseg->mapper_xp;
     959        xptr_t mapper_xp = vseg->mapper_xp;
    838960
    839961        assert( (mapper_xp != XPTR_NULL), __FUNCTION__,
     
    856978        if ( page_ptr == NULL ) return EINVAL;
    857979
    858         page_cxy = mapper_cxy;
     980        page_xp = XPTR( mapper_cxy , page_ptr );
    859981    }
    860982
    861983    // Other types : allocate a physical page from target cluster,
     984    // as defined by vseg type and vpn value
    862985    else
    863986    {
    864         uint32_t flags = vseg->flags;
    865 
    866         // get target cluster for physical page
    867         if( flags & VSEG_DISTRIB ) // depends on VPN LSB
    868         {
    869             uint32_t x_size = LOCAL_CLUSTER->x_size;
    870             uint32_t y_size = LOCAL_CLUSTER->y_size;
    871             page_cxy = vpn & ((x_size * y_size) - 1);
    872         }
    873         else                       // defined in vseg descriptor
    874         {
    875             page_cxy = vseg->cxy;
    876         }
    877 
    878         // allocate a physical page in target cluster
    879         kmem_req_t   req;
    880         if( page_cxy == local_cxy )  // target cluster is the local cluster
    881         {
    882             req.type  = KMEM_PAGE;
    883             req.size  = 0;
    884             req.flags = AF_NONE;
    885             page_ptr  = (page_t *)kmem_alloc( &req );
    886         }
    887         else                           // target cluster is not the local cluster
    888         {
    889             rpc_pmem_get_pages_client( page_cxy , 0 , &page_ptr );
    890         }
    891 
    892         if( page_ptr == NULL ) return ENOMEM;
     987        // allocate physical page
     988        page_xp = vmm_page_allocate( vseg , vpn );
     989
     990        if( page_xp == XPTR_NULL ) return ENOMEM;
    893991
    894992        // initialise missing page from .elf file mapper for DATA and CODE types
     
    9121010            uint32_t elf_offset = vseg->file_offset + offset;
    9131011
    914             vmm_dmsg("\n[DMSG] %s : core[%x,%d] for vpn = %x / elf_offset = %x\n",
    915             __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn, elf_offset );
     1012vmm_dmsg("\n[DBG] %s : core[%x,%d] for vpn = %x / elf_offset = %x\n",
     1013__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn, elf_offset );
    9161014
    9171015            // compute extended pointer on page base
    918             xptr_t base_xp  = ppm_page2base( XPTR( page_cxy , page_ptr ) );
     1016            xptr_t base_xp  = ppm_page2base( page_xp );
    9191017
    9201018            // file_size (in .elf mapper) can be smaller than vseg_size (BSS)
     
    9231021            if( file_size < offset )                 // missing page fully in  BSS
    9241022            {
    925                 vmm_dmsg("\n[DMSG] %s : core[%x,%d] for vpn = %x / fully in BSS\n",
    926                 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn );
    927 
    928                 if( page_cxy == local_cxy )
     1023vmm_dmsg("\n[DBG] %s : core[%x,%d] for vpn = %x / fully in BSS\n",
     1024__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn );
     1025
     1026                if( GET_CXY( page_xp ) == local_cxy )
    9291027                {
    9301028                    memset( GET_PTR( base_xp ) , 0 , CONFIG_PPM_PAGE_SIZE );
     
    9371035            else if( file_size >= (offset + CONFIG_PPM_PAGE_SIZE) )  // fully in  mapper
    9381036            {
    939                 vmm_dmsg("\n[DMSG] %s : core[%x,%d] for vpn = %x / fully in mapper\n",
    940                 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn );
     1037
     1038vmm_dmsg("\n[DBG] %s : core[%x,%d] for vpn = %x / fully in mapper\n",
     1039__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn );
    9411040
    9421041                if( mapper_cxy == local_cxy )
     
    9651064                  // - (page_size + offset - file_size) bytes from BSS
    9661065            {
    967                 vmm_dmsg("\n[DMSG] %s : core[%x,%d] for vpn = %x / both mapper & BSS\n"
    968                          "      %d bytes from mapper / %d bytes from BSS\n",
    969                 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn,
    970                 file_size - offset , offset + CONFIG_PPM_PAGE_SIZE - file_size  );
     1066
     1067vmm_dmsg("\n[DBG] %s : core[%x,%d] for vpn = %x / both mapper & BSS\n"
     1068         "      %d bytes from mapper / %d bytes from BSS\n",
     1069__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn,
     1070file_size - offset , offset + CONFIG_PPM_PAGE_SIZE - file_size  );
    9711071
    9721072                // initialize mapper part
     
    9931093
    9941094                // initialize BSS part
    995                 if( page_cxy == local_cxy )
     1095                if( GET_CXY( page_xp ) == local_cxy )
    9961096                {
    9971097                    memset( GET_PTR( base_xp ) + file_size - offset , 0 ,
     
    10081108
    10091109    // return ppn
    1010     *ppn = ppm_page2ppn( XPTR( page_cxy , page_ptr ) );
    1011 
    1012     vmm_dmsg("\n[DMSG] %s : core[%x,%d] exit for vpn = %x / ppn = %x\n",
    1013     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , *ppn );
     1110    *ppn = ppm_page2ppn( page_xp );
     1111
     1112vmm_dmsg("\n[DBG] %s : core[%x,%d] exit for vpn = %x / ppn = %x\n",
     1113__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , *ppn );
    10141114
    10151115    return 0;
     
    10201120error_t vmm_get_pte( process_t * process,
    10211121                     vpn_t       vpn,
    1022                      uint32_t  * ret_attr,
    1023                      ppn_t     * ret_ppn )
    1024 {
    1025     vseg_t  * vseg;   // pointer on vseg containing VPN
    1026     ppn_t     ppn;    // physical page number
    1027     uint32_t  attr;   // attributes from GPT entry
     1122                     bool_t      cow,
     1123                     uint32_t  * attr,
     1124                     ppn_t     * ppn )
     1125{
     1126    vseg_t  * vseg;       // pointer on vseg containing VPN
     1127    ppn_t     old_ppn;    // current PTE_PPN
     1128    uint32_t  old_attr;   // current PTE_ATTR
     1129    ppn_t     new_ppn;    // new PTE_PPN
     1130    uint32_t  new_attr;   // new PTE_ATTR
     1131    xptr_t    page_xp;    // extended pointer on allocated page descriptor
    10281132    error_t   error;
    10291133
     
    10321136    "not called in the reference cluster\n" );
    10331137
    1034     vmm_dmsg("\n[DMSG] %s : core[%x,%d] enter for vpn = %x in process %x\n",
    1035     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , process->pid );
     1138vmm_dmsg("\n[DBG] %s : core[%x,%d] enter for vpn = %x in process %x / cow = %d\n",
     1139__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , process->pid , %d);
    10361140
    10371141    // get VMM pointer
    10381142    vmm_t * vmm = &process->vmm;
    10391143
    1040     // access GPT to get PTE attributes and PPN
    1041     hal_gpt_get_pte( &vmm->gpt , vpn , &attr , &ppn );
    1042 
    1043     // if PTE is unmapped
    1044     // 1) get VSEG containing the missing VPN
    1045     // 2) get & initialize physical page (depending on vseg type),
    1046     // 3) register the PTE in reference GPT
    1047     if( (attr & GPT_MAPPED) == 0 )
    1048     {
    1049         vmm_dmsg("\n[DMSG] %s : core[%x,%d] page %x unmapped => try to map it\n",
    1050         __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn );
    1051 
    1052         // 1. get vseg pointer
    1053         error = vmm_get_vseg( process , vpn<<CONFIG_PPM_PAGE_SHIFT , &vseg );
     1144    // get vseg pointer from ref VSL
     1145    error = vmm_get_vseg( process , vpn<<CONFIG_PPM_PAGE_SHIFT , &vseg );
     1146
     1147    if( error )
     1148    {
     1149        printk("\n[ERROR] in %s : out of segment / process = %x / vpn = %x\n",
     1150        __FUNCTION__ , process->pid , vpn );
     1151        return error;
     1152    }
     1153
     1154vmm_dmsg("\n[DBG] %s : core[%x,%d] found vseg %s / vpn_base = %x / vpn_size = %x\n",
     1155__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid ,
     1156vseg_type_str(vseg->type) , vseg->vpn_base , vseg->vpn_size );
     1157
     1158    // access GPT to get current PTE attributes and PPN
     1159    hal_gpt_get_pte( &vmm->gpt , vpn , &old_attr , &old_ppn );
     1160
     1161    // for both copy_on_write and page_fault events, we allocate a physical page,
     1162    // initialize it, register it in the GPT, and return the new_ppn and new_attr
     1163
     1164    if( cow )               ////////////// copy_on_write request ///////////
     1165    {
     1166        assert( (*attr & GPT_MAPPED) , __FUNCTION__ ,
     1167        "PTE must be mapped for a copy-on-write\n" );
     1168
     1169vmm_dmsg("\n[DBG] %s : core[%x,%d] page %x must be copied => do it\n",
     1170__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn );
     1171
     1172        // allocate a physical page depending on vseg type
     1173        page_xp = vmm_page_allocate( vseg , vpn );
     1174
     1175        if( page_xp == XPTR_NULL )
     1176        {
     1177            printk("\n[ERROR] in %s : no memory / process = %x / vpn = %x\n",
     1178            __FUNCTION__ , process->pid , vpn );
     1179            return ENOMEM;
     1180        }
     1181
     1182        // compute allocated page PPN
     1183        new_ppn = ppm_page2ppn( page_xp );
     1184
     1185        // copy old page content to new page
     1186        xptr_t  old_base_xp = ppm_ppn2base( old_ppn );
     1187        xptr_t  new_base_xp = ppm_ppn2base( new_ppn );
     1188        memcpy( GET_PTR( new_base_xp ),
     1189                GET_PTR( old_base_xp ),
     1190                CONFIG_PPM_PAGE_SIZE );
     1191
     1192        // update attributes: reset COW and set WRITABLE
     1193        new_attr = old_attr & ~GPT_COW; 
     1194        new_attr = new_attr | GPT_WRITABLE;
     1195
     1196        // register PTE in GPT
     1197        error = hal_gpt_set_pte( &vmm->gpt , vpn , new_ppn , new_attr );
    10541198
    10551199        if( error )
    10561200        {
    1057             printk("\n[ERROR] in %s : out of segment / process = %x / vpn = %x\n",
    1058                    __FUNCTION__ , process->pid , vpn );
     1201            printk("\n[ERROR] in %s : cannot update GPT / process = %x / vpn = %x\n",
     1202            __FUNCTION__ , process->pid , vpn );
    10591203            return error;
    10601204        }
    1061 
    1062         vmm_dmsg("\n[DMSG] %s : core[%x,%d] found vseg %s / vpn_base = %x / vpn_size = %x\n",
    1063         __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid ,
    1064         vseg_type_str(vseg->type) , vseg->vpn_base , vseg->vpn_size );
    1065 
    1066         // 2. get physical page number, depending on vseg type
    1067         error = vmm_get_one_ppn( vseg , vpn , &ppn );
    1068 
    1069         if( error )
     1205    }
     1206    else                    //////////////////// page_fault request ///////////
     1207    { 
     1208        if( (old_attr & GPT_MAPPED) == 0 )    // PTE unmapped in ref GPT
    10701209        {
    1071             printk("\n[ERROR] in %s : cannot allocate memory / process = %x / vpn = %x\n",
    1072                    __FUNCTION__ , process->pid , vpn );
    1073             return error;
     1210
     1211vmm_dmsg("\n[DBG] %s : core[%x,%d] page %x unmapped => try to map it\n",
     1212__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn );
     1213
     1214            // allocate one physical page, depending on vseg type
     1215            error = vmm_get_one_ppn( vseg , vpn , &new_ppn );
     1216
     1217            if( error )
     1218            {
     1219                printk("\n[ERROR] in %s : no memory / process = %x / vpn = %x\n",
     1220                __FUNCTION__ , process->pid , vpn );
     1221                return error;
     1222            }
     1223
     1224            // define attributes from vseg flags
     1225            new_attr = GPT_MAPPED | GPT_SMALL;
     1226            if( vseg->flags & VSEG_USER  ) new_attr |= GPT_USER;
     1227            if( vseg->flags & VSEG_WRITE ) new_attr |= GPT_WRITABLE;
     1228            if( vseg->flags & VSEG_EXEC  ) new_attr |= GPT_EXECUTABLE;
     1229            if( vseg->flags & VSEG_CACHE ) new_attr |= GPT_CACHABLE;
     1230
     1231            // register PTE in GPT
     1232            error = hal_gpt_set_pte( &vmm->gpt , vpn , new_ppn , new_attr );
     1233
     1234            if( error )
     1235            {
     1236                printk("\n[ERROR] in %s : cannot update GPT / process = %x / vpn = %x\n",
     1237                __FUNCTION__ , process->pid , vpn );
     1238                return error;
     1239            }
    10741240        }
    1075 
    1076         // 3. define attributes from vseg flags and register in GPT
    1077         attr = GPT_MAPPED | GPT_SMALL;
    1078         if( vseg->flags & VSEG_USER  ) attr |= GPT_USER;
    1079         if( vseg->flags & VSEG_WRITE ) attr |= GPT_WRITABLE;
    1080         if( vseg->flags & VSEG_EXEC  ) attr |= GPT_EXECUTABLE;
    1081         if( vseg->flags & VSEG_CACHE ) attr |= GPT_CACHABLE;
    1082 
    1083         error = hal_gpt_set_pte( &vmm->gpt , vpn , ppn , attr );
    1084 
    1085         if( error )
     1241        else
    10861242        {
    1087             printk("\n[ERROR] in %s : cannot register PTE / process = %x / vpn = %x\n",
    1088                    __FUNCTION__ , process->pid , vpn );
    1089             return error;
     1243            new_attr = old_attr;
     1244            new_ppn  = old_ppn;
    10901245        }
    1091     }  // end new PTE
    1092 
    1093     vmm_dmsg("\n[DMSG] %s : core[%x,%d] exit for vpn = %x / ppn = %x\n",
    1094     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , ppn );
    1095 
    1096     *ret_ppn  = ppn;
    1097     *ret_attr = attr;
     1246    }
     1247
     1248vmm_dmsg("\n[DBG] %s : core[%x,%d] exit for vpn = %x / ppn = %x / attr = %x\n",
     1249__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , new_ppn , new_attr );
     1250
     1251    *ppn  = new_ppn;
     1252    *attr = new_attr;
    10981253    return 0;
    10991254
     
    11061261    uint32_t         attr;          // missing page attributes
    11071262    ppn_t            ppn;           // missing page PPN
    1108     error_t          error;         // return value
     1263    error_t          error;
    11091264
    11101265    // get reference process cluster and local pointer
     
    11131268
    11141269    // get missing PTE attributes and PPN from reference cluster
    1115     if( local_cxy != ref_cxy )   // local cluster is not the reference cluster
    1116     {
    1117         rpc_vmm_get_pte_client( ref_cxy , ref_ptr , vpn , &attr , &ppn , &error );
    1118     }
    1119     else                              // local cluster is the reference cluster
    1120     {
    1121         error = vmm_get_pte( process , vpn , &attr , &ppn );
     1270    if( local_cxy != ref_cxy ) 
     1271    {
     1272        rpc_vmm_get_pte_client( ref_cxy,
     1273                                ref_ptr,
     1274                                vpn,
     1275                                false,    // page_fault
     1276                                &attr,
     1277                                &ppn,
     1278                                &error );
     1279
     1280        // get local VMM pointer
     1281        vmm_t * vmm = &process->vmm;
     1282
     1283        // update local GPT
     1284        error |= hal_gpt_set_pte( &vmm->gpt , vpn , ppn , attr );
     1285    }
     1286    else   // local cluster is the reference cluster
     1287    {
     1288        error = vmm_get_pte( process,
     1289                             vpn,
     1290                             false,      // page-fault
     1291                             &attr,
     1292                             &ppn );
    11221293    }
    11231294
     
    11261297}  // end vmm_handle_page_fault()
    11271298
     1299///////////////////////////////////////////////
     1300error_t vmm_copy_on_write( process_t * process,
     1301                           vpn_t       vpn )
     1302{
     1303    uint32_t         attr;          // missing page attributes
     1304    ppn_t            ppn;           // missing page PPN
     1305    error_t          error;
     1306
     1307    // get reference process cluster and local pointer
     1308    cxy_t       ref_cxy = GET_CXY( process->ref_xp );
     1309    process_t * ref_ptr = (process_t *)GET_PTR( process->ref_xp );
     1310
     1311    // get new PTE attributes and PPN from reference cluster
     1312    if( local_cxy != ref_cxy )
     1313    {
     1314        rpc_vmm_get_pte_client( ref_cxy,
     1315                                ref_ptr,
     1316                                vpn,
     1317                                true,     // copy-on-write
     1318                                &attr,
     1319                                &ppn,
     1320                                &error );
     1321
     1322        // get local VMM pointer
     1323        vmm_t * vmm = &process->vmm;
     1324
     1325        // update local GPT
     1326        error |= hal_gpt_set_pte( &vmm->gpt , vpn , ppn , attr );
     1327    }
     1328    else   // local cluster is the reference cluster
     1329    {
     1330        error = vmm_get_pte( process,
     1331                             vpn,
     1332                             true,      // copy-on-write
     1333                             &attr,
     1334                             &ppn );
     1335    }
     1336
     1337    return error;
     1338
     1339}  // end vmm_copy_on_write()
    11281340
    11291341///////////////////////////////////////////
     
    11521364    if( local_cxy == GET_CXY( process->ref_xp) ) // calling process is reference process
    11531365    {
    1154         error = vmm_get_pte( process, vpn , &attr , &ppn );
     1366        error = vmm_get_pte( process, vpn , false , &attr , &ppn );
    11551367    }
    11561368    else                                         // calling process is not reference process
     
    11581370        cxy_t       ref_cxy = GET_CXY( process->ref_xp );
    11591371        process_t * ref_ptr = (process_t *)GET_PTR( process->ref_xp );
    1160         rpc_vmm_get_pte_client( ref_cxy , ref_ptr , vpn , &attr , &ppn , &error );
     1372        rpc_vmm_get_pte_client( ref_cxy , ref_ptr , vpn , false , &attr , &ppn , &error );
    11611373    }
    11621374
  • trunk/kernel/mm/vmm.h

    r406 r407  
    4040
    4141/*********************************************************************************************
    42  * This structure defines the STACK allocator used by the VMM to dynamically allocate
    43  * STACK vsegs requested or released by the user process.
    44  * This allocator handles a fixed size array of fixed size slots stores in the STACK zone.
     42 * This structure defines the STACK allocator used by the VMM to dynamically handle
     43 * a STACK vseg requested or released by an user process.
     44 * This allocator handles a fixed size array of fixed size slots in the STACK zone.
    4545 * The stack size and the number of slots are defined by the CONFIG_VMM_STACK_SIZE, and
    46  * CONFIG_THREAD
     46 * CONFIG_VMM_STACK_BASE parameters.
    4747 * Each slot can contain one user stack vseg. The first page in the slot is not allocated
    4848 * to detect stack overflow.
     
    5050 * All allocation / release operations are registered in the stack_bitmap, that completely
    5151 * define the STACK zone state.
    52  * In this implementation, the max number of slots is 32.
    5352 ********************************************************************************************/
    5453
     
    6261
    6362/*********************************************************************************************
    64  * This structure defines the MMAP allocator used by the VMM to dynamically allocate
     63 * This structure defines the MMAP allocator used by the VMM to dynamically handle 
    6564 * MMAP vsegs requested or released by an user process.
    6665 * This allocator should be only used in the reference cluster.
     
    9291 * This local VMM provides three main services:
    9392 * 1) It registers all vsegs statically or dynamically defined in the vseg list.
    94  * 2) It allocates virtual memory space for the STACKS and MMAP vsegs.
     93 * 2) It allocates virtual memory space for the STACKS and MMAP vsegs (FILE/ANON/REMOTE).
    9594 * 3) It contains the local copy of the generic page table descriptor.
    9695 ********************************************************************************************/
     
    9897typedef struct vmm_s
    9998{
    100         rwlock_t       vsegs_lock;         /*! lock protecting the vsegs list & radix tree      */
     99        rwlock_t       vsegs_lock;         /*! lock protecting the vsegs list                   */
    101100        list_entry_t   vsegs_root;         /*! all vsegs in same process and same cluster       */
    102101        uint32_t       vsegs_nr;           /*! total number of local vsegs                      */
     
    107106    mmap_mgr_t     mmap_mgr;           /*! embedded MMAP vsegs allocator                    */
    108107
    109         uint32_t       pgfault_nr;         /*! page fault counter                               */
     108        uint32_t       pgfault_nr;         /*! page fault counter (instrumentation)             */
    110109        uint32_t       u_err_nr;           /*! TODO ??? [AG]                                    */
    111110        uint32_t       m_err_nr;           /*! TODO ??? [AG]                                    */
     
    119118
    120119        intptr_t       entry_point;        /*! main thread entry point                          */
    121 
    122     vseg_t       * heap_vseg;          /*! pointer on local heap vseg descriptor            */
    123120}
    124121vmm_t;
    125122
    126123/*********************************************************************************************
    127  * This structure is used to store the arguments of the mmap() system call.
    128  ********************************************************************************************/
    129 
    130 typedef struct mmap_attr_s
    131 {
    132         void     * addr;            /*! requested virtual address (unused : should be NULL)     */
    133         uint32_t   length;          /*! requested vseg size (bytes)                             */
    134         uint32_t   prot;            /*! access modes                                            */
    135         uint32_t   flags;           /*! only MAP_FILE / MAP_ANON / MAP_PRIVATE / MAP_SHARED     */
    136         fdid_t     fdid;            /*! file descriptor index (if MAP_FILE is set)              */
    137         int32_t    offset;          /*! file offset (if MAP_FILE is set)                        */
    138 }
    139 mmap_attr_t;
    140 
    141 /*********************************************************************************************
    142124 * This function initialises the virtual memory manager attached to an user process.
    143  * - It registers the "kentry", "args", "envs" and "heap" vsegs in the vsegs list.
    144  *   The "code" and "data" vsegs are registered by the elf_load_process() function,
    145  *   the "stack" vsegs are registered by the thread_user_create() function, and the
    146  *   "mmap" vsegs are dynamically created by syscalls.
     125 * - It initializes the STACK and MMAP allocators.
     126 * - It registers the "kentry", "args", "envs" vsegs in the VSL.
     127 * - The "code" and "data" vsegs are registered by the elf_load_process() function.
     128 * - The "stack" vsegs are dynamically created by the thread_user_create() function.
     129 * - The "file", "anon", "remote" vsegs are dynamically created by the mmap() syscalls.
    147130 * - It initializes the generic page table, calling the HAL specific hal_gpt_init() function.
    148  *   For TSAR it map all pages for the "kentry" vseg, that must be identity mapping.
    149  * - It initializes the STAK and MMAP allocators.
     131 * - For TSAR it map all pages for the "kentry" vseg, that must be identity mapping.
    150132 * TODO : Any error in this function gives a kernel panic => improve error handling.
    151133 *********************************************************************************************
     
    155137
    156138/*********************************************************************************************
    157  * This function copies the content of a source VMM to a destination VMM.
     139 * This function displays on TXY0 the list or registered vsegs for a given <process>.
     140 * If the <mapping> argument is true, it displays for each vesg all mapped PTEs in GPT.
     141 *********************************************************************************************
     142 * @ process   : pointer on process descriptor.
     143 * @ mapping   : detailed mapping if true.
     144 ********************************************************************************************/
     145void vmm_display( struct process_s * process,
     146                  bool_t             mapping );
     147
     148/*********************************************************************************************
     149 * This function is called by the sys_fork() system call.
     150 * It copies the content of a parent process descriptor VMM to a child process VMM.
     151 * - All vsegs registered in the source VSL are copied in the destination VSL.
     152 * - All PTEs registered in the source GPT are copied in destination GPT. For all writable
     153 *   PTEs - but the FILE vsegs - the WRITABLE flag is reset and the COW flag is set in
     154 *   the destination GPT.
    158155 *********************************************************************************************
    159156 * @ dst_process   : pointer on destination process descriptor.
     
    187184/*********************************************************************************************
    188185 * This function allocates memory for a vseg descriptor, initialises it, and register it
    189  * in the VMM of the process. It checks the collision with pre-existing vsegs in VMM.
    190  * For STACK and MMAP types vseg, it does not use the base argument, but uses the VMM STACK
    191  * and MMAP specific allocators to get a base address in virtual space.
    192  * To comply with the "on-demand" paging policy, this function does NOT modify the
    193  * page table, and does not allocate physical memory for vseg data.
    194  *********************************************************************************************
    195  * @ vmm   : pointer on process descriptor.
    196  * @ base      : vseg base address
    197  * @ size      : vseg size (bytes)
    198  * @ type      : vseg type
    199  * @ returns pointer on vseg if success / returns NULL if no memory or conflict.
     186 * in the VMM of the local process descriptor, that should be the reference process.
     187 * For the 'stack", "file", "anon", & "remote" types, it does not use the <base> argument,
     188 * but uses the STACK and MMAP virtual memory allocators.
     189 * It checks collision with all pre-existing vsegs.
     190 * To comply with the "on-demand" paging policy, this function does NOT modify the page table,
     191 * and does not allocate physical memory for vseg data.
     192 * It should be called by a local thread (could be a RPC thread if the client thread is not
     193 * running in the regerence cluster).
     194 *********************************************************************************************
     195 * @ process     : pointer on local processor descriptor.
     196 * @ type        : vseg type.
     197 * @ base        : vseg base address (not used for dynamically allocated vsegs).
     198 * @ size        : vseg size (bytes).
     199 * @ file_offset : offset in file for CODE, DATA, FILE types.
     200 * @ file_size   : can be smaller than "size" for DATA type.
     201 * @ mapper_xp   : extended pointer on mapper for CODE, DATA, FILE types.
     202 * @ cxy         : physical mapping cluster (for non distributed vsegs).
     203 * @ returns pointer on vseg if success / returns NULL if no memory, or conflict.
    200204 ********************************************************************************************/
    201205vseg_t * vmm_create_vseg( struct process_s * process,
     206                          vseg_type_t        type,
    202207                          intptr_t           base,
    203                               intptr_t           size,
    204                               uint32_t           type );
     208                              uint32_t           size,
     209                          uint32_t           file_offset,
     210                          uint32_t           file_size,
     211                          xptr_t             mapper_xp,
     212                          cxy_t              cxy );
    205213
    206214/*********************************************************************************************
     
    245253/*********************************************************************************************
    246254 * This function removes a given region (defined by a base address and a size) from
    247  * the VMM of a given process descriptor. This can modify several vsegs:
     255 * the VMM of a given process descriptor. This can modify the number of vsegs:
    248256 * (a) if the region is not entirely mapped in an existing vseg, it's an error.
    249257 * (b) if the region has same base and size as an existing vseg, the vseg is removed.
     
    251259 * (d) if the removed region cut the vseg in three parts, it is modified, and a new
    252260 *     vseg is created with same type.
     261 * FIXME [AG] this function must be called by a thread running in the reference cluster,
     262 * and the VMM must be updated in all process descriptors copies.
    253263 *********************************************************************************************
    254264 * @ process   : pointer on process descriptor
     
    279289
    280290/*********************************************************************************************
    281  * This function is called by the generic exception handler when a page fault
     291 * This function is called by the generic exception handler when a page-fault event
    282292 * has been detected in a given cluster.
     293 * - If the local cluster is the reference, it call directly the vmm_get_pte() function.
    283294 * - If the local cluster is not the reference cluster, it send a RPC_VMM_GET_PTE
    284  *   to the reference cluster to get the missing PTE attributes and PPN, and update
    285  *   the local page table.
    286  * - If the local cluster is the reference, it call directly the vmm_get_pte() function.
     295 *   to the reference cluster to get the missing PTE attributes and PPN,
     296 *   and update the local page table.
    287297 *********************************************************************************************
    288298 * @ process   : pointer on process descriptor.
     
    294304
    295305/*********************************************************************************************
    296  * This function returns in the "attr" and "ppn" arguments the PTE associated to a given
    297  * VPN for a given process. This function must be called by a thread running in the
    298  * reference cluster. To get the PTE from another cluster, use the RPC_VMM_GET_PTE.
    299  * The vseg containing the searched VPN should be registered in the reference VMM.
    300  * If the PTE in the reference page table is unmapped, this function allocates the missing
    301  * physical page from the target cluster defined by the vseg type, initialize it,
    302  * and update the reference page table. It calls the RPC_PMEM_GET_PAGES to get and
    303  * initialize the missing physical page, if the target cluster is not the reference cluster.
     306 * This function is called by the generic exception handler when a copy-on-write event
     307 * has been detected in a given cluster.
     308 * - If the local cluster is the reference, it call directly the vmm_get_pte() function.
     309 * - If the local cluster is not the reference cluster, it send a RPC_VMM_GET_PTE
     310 *   to the reference cluster to get the missing PTE attributes and PPN,
     311 *   and update the local page table.
     312 *********************************************************************************************
     313 * @ process   : pointer on process descriptor.
     314 * @ vpn       : VPN of the missing PTE.
     315 * @ returns 0 if success / returns ENOMEM if no memory.
     316 ********************************************************************************************/
     317error_t vmm_copy_on_write( struct process_s * process,
     318                           vpn_t              vpn );
     319
     320/*********************************************************************************************
     321 * This function is called when a new PTE (GPT entry) is required because a "page-fault",
     322 * or "copy-on_write" event has been detected for a given <vpn> in a given <process>.
     323 * The <cow> argument defines the type of event to be handled.
     324 * This function must be called by a thread running in reference cluster, and the vseg
     325 * containing the searched VPN should be registered in the reference VMM.
     326 * - for an actual page-fault, it allocates the missing physical page from the target cluster
     327 *   defined by the vseg type, initialize it, and update the reference page table.
     328 * - for a copy-on-write, it allocates a new physical page from the target cluster,
     329 *   initialise it from the old physical page, and update the reference page table.
     330 * In both cases, it calls the RPC_PMEM_GET_PAGES to get the new physical page if the
     331 * target cluster is not the reference cluster.
     332 * It returns in the <attr> and <ppn> arguments the accessed or modified PTE.
    304333 *********************************************************************************************
    305334 * @ process   : [in] pointer on process descriptor.
    306335 * @ vpn       : [in] VPN defining the missing PTE.
     336 * @ cow       : [in] "copy_on_write" if true / "page_fault" if false.
    307337 * @ attr      : [out] PTE attributes.
    308338 * @ ppn       : [out] PTE ppn.
     
    311341error_t vmm_get_pte( struct process_s * process,
    312342                     vpn_t              vpn,
     343                     bool_t             cow,
    313344                     uint32_t         * attr,
    314345                     ppn_t            * ppn );
  • trunk/kernel/mm/vseg.c

    r406 r407  
    5252        if     ( vseg_type == VSEG_TYPE_CODE   ) return "CODE";
    5353        else if( vseg_type == VSEG_TYPE_DATA   ) return "DATA";
    54         else if( vseg_type == VSEG_TYPE_HEAP   ) return "HEAP";
    55         else if( vseg_type == VSEG_TYPE_STACK  ) return "STACK";
     54        else if( vseg_type == VSEG_TYPE_STACK  ) return "STAK";
    5655        else if( vseg_type == VSEG_TYPE_ANON   ) return "ANON";
    5756        else if( vseg_type == VSEG_TYPE_FILE   ) return "FILE";
    58         else if( vseg_type == VSEG_TYPE_REMOTE ) return "REMOTE";
    59         else if( vseg_type == VSEG_TYPE_KCODE  ) return "KCODE";
    60         else if( vseg_type == VSEG_TYPE_KDATA  ) return "KDATA";
    61         else if( vseg_type == VSEG_TYPE_KDEV   ) return "KDEV";
     57        else if( vseg_type == VSEG_TYPE_REMOTE ) return "REMO";
    6258    else                                     return "undefined";
    6359}
     
    8783///////////////////////////////////
    8884void vseg_init( vseg_t      * vseg,
     85                vseg_type_t   type,
    8986                    intptr_t      base,
    90                 intptr_t      size,
     87                uint32_t      size,
    9188                vpn_t         vpn_base,
    9289                vpn_t         vpn_size,
    93                         uint32_t      type,
     90                        uint32_t      file_offset,
     91                uint32_t      file_size,
     92                xptr_t        mapper_xp,
    9493                cxy_t         cxy )
    9594{
    96     vseg->type      = type;
    97         vseg->min       = base;
    98         vseg->max       = base + size;
    99     vseg->vpn_base  = vpn_base;
    100         vseg->vpn_size  = vpn_size;
    101         vseg->mapper_xp = XPTR_NULL;
    102     vseg->cxy       = cxy;
     95    vseg->type        = type;
     96        vseg->min         = base;
     97        vseg->max         = base + size;
     98    vseg->vpn_base    = vpn_base;
     99        vseg->vpn_size    = vpn_size;
     100    vseg->file_offset = file_offset;
     101    vseg->file_size   = file_size;
     102        vseg->mapper_xp   = mapper_xp;
     103    vseg->cxy         = cxy;
    103104
    104105    // set vseg flags depending on type
     
    124125                      VSEG_DISTRIB ;
    125126    }
    126     else if( type == VSEG_TYPE_HEAP )
    127     {
    128         vseg->flags = VSEG_USER    |
    129                       VSEG_WRITE   |
    130                       VSEG_CACHE   |
    131                       VSEG_DISTRIB ;
    132     }
    133127    else if( type == VSEG_TYPE_REMOTE )
    134128    {
     
    141135        vseg->flags = VSEG_USER    |
    142136                      VSEG_WRITE   |
    143                       VSEG_CACHE   |
    144                       VSEG_DISTRIB ;
     137                      VSEG_CACHE;
    145138    }
    146139    else if( type == VSEG_TYPE_FILE )
     
    161154                      VSEG_CACHE   |
    162155                      VSEG_PRIVATE ;
     156    }
     157    else if( type == VSEG_TYPE_KDEV )
     158    {
     159        vseg->flags = VSEG_WRITE   ;
    163160    }
    164161    else
     
    171168//////////////////////////////////////////
    172169void vseg_init_from_ref( vseg_t    * vseg,
    173                          xptr_t      ref )
     170                         xptr_t      ref_xp )
    174171{
    175172    // get remote vseg cluster and pointer
    176     cxy_t    cxy = (cxy_t   )GET_CXY( ref );
    177     vseg_t * ptr = (vseg_t *)GET_PTR( ref );
     173    cxy_t    cxy = (cxy_t   )GET_CXY( ref_xp );
     174    vseg_t * ptr = (vseg_t *)GET_PTR( ref_xp );
    178175
    179176    // initialize vseg with remote_read access
    180     vseg->type       =           hal_remote_lw ( XPTR( cxy , &ptr->type      ) );
    181     vseg->min        = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->min       ) );
    182     vseg->max        = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->max       ) );
    183     vseg->vpn_base   =           hal_remote_lw ( XPTR( cxy , &ptr->vpn_base  ) );
    184     vseg->vpn_size   =           hal_remote_lw ( XPTR( cxy , &ptr->vpn_size  ) );
    185     vseg->flags      =           hal_remote_lw ( XPTR( cxy , &ptr->flags     ) );
    186         vseg->mapper_xp  = (xptr_t)  hal_remote_lwd( XPTR( cxy , &ptr->mapper_xp ) );
     177    vseg->type        =           hal_remote_lw ( XPTR( cxy , &ptr->type        ) );
     178    vseg->min         = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->min         ) );
     179    vseg->max         = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->max         ) );
     180    vseg->vpn_base    =           hal_remote_lw ( XPTR( cxy , &ptr->vpn_base    ) );
     181    vseg->vpn_size    =           hal_remote_lw ( XPTR( cxy , &ptr->vpn_size    ) );
     182    vseg->flags       =           hal_remote_lw ( XPTR( cxy , &ptr->flags       ) );
     183    vseg->file_offset =           hal_remote_lw ( XPTR( cxy , &ptr->file_offset ) );
     184    vseg->file_size   =           hal_remote_lw ( XPTR( cxy , &ptr->file_size   ) );
     185        vseg->mapper_xp   = (xptr_t)  hal_remote_lwd( XPTR( cxy , &ptr->mapper_xp   ) );
    187186}
    188187
  • trunk/kernel/mm/vseg.h

    r406 r407  
    3636
    3737/**********************************************************************************************
    38  * This enum defines the vseg types
     38 * This enum defines the vseg types for an user process.
    3939 *********************************************************************************************/
    4040
    41 enum
     41typedef enum
    4242{
    43     VSEG_TYPE_CODE   = 0,          /*! executable code        / private / localized          */
    44     VSEG_TYPE_DATA   = 1,          /*! initialized data       / public  / distributed        */
    45     VSEG_TYPE_HEAP   = 2,          /*! standard malloc        / public  / distributed        */
    46     VSEG_TYPE_STACK  = 3,          /*! execution stack        / private / localized          */
    47     VSEG_TYPE_ANON   = 4,          /*! anonymous mmap         / public  / localized          */
    48     VSEG_TYPE_FILE   = 5,          /*! file mmap              / public  / localized          */
    49     VSEG_TYPE_REMOTE = 6,          /*! remote mmap            / public  / localized          */
    50     VSEG_TYPE_KCODE  = 7,          /*! kernel code            / private / localized          */
    51     VSEG_TYPE_KDATA  = 8,          /*! kernel data            / private / localized          */
    52     VSEG_TYPE_KDEV   = 9,          /*! device segment         / public  / localized          */
     43    VSEG_TYPE_CODE   = 0,          /*! executable user code   / private / localized          */
     44    VSEG_TYPE_DATA   = 1,          /*! initialized user data  / public  / distributed        */
     45    VSEG_TYPE_STACK  = 2,          /*! execution user stack   / private / localized          */
     46    VSEG_TYPE_ANON   = 3,          /*! anonymous mmap         / public  / localized          */
     47    VSEG_TYPE_FILE   = 4,          /*! file mmap              / public  / localized          */
     48    VSEG_TYPE_REMOTE = 5,          /*! remote mmap            / public  / localized          */
    5349
    54     VSEG_TYPES_NR    = 10,
    55 };
     50    VSEG_TYPE_KDATA  = 10,
     51    VSEG_TYPE_KCODE  = 11,
     52    VSEG_TYPE_KDEV   = 12,
     53}
     54vseg_type_t;
    5655
    5756
     
    8180        vpn_t             vpn_size;     /*! number of pages occupied                             */
    8281        uint32_t          flags;        /*! vseg attributes                                      */
    83         xptr_t            mapper_xp;    /*! xptr on remote mapper (for types CODE / DATA / FILE) */
    84         intptr_t          file_offset;  /*! vseg offset in file (for types CODE/DATA)            */
     82        xptr_t            mapper_xp;    /*! xptr on remote mapper (for types CODE/DATA/FILE)    */
     83        intptr_t          file_offset;  /*! vseg offset in file (for types CODE/DATA/FILE        */
    8584    intptr_t          file_size;    /*! max segment size in mapper (for type CODE/DATA)      */
    8685    cxy_t             cxy;          /*! physical mapping (for non distributed vseg)          */
     
    125124 *********************************************************************************************/
    126125void vseg_init( vseg_t      * vseg,
     126                    vseg_type_t   type,
    127127                intptr_t      base,
    128                     intptr_t      size,
     128                    uint32_t      size,
    129129                vpn_t         vpn_base,
    130130                vpn_t         vpn_size,
    131                     uint32_t      type,
     131                uint32_t      file_offset,
     132                uint32_t      file_size,
     133                xptr_t        mapper_xp,
    132134                cxy_t         cxy );
    133135
  • trunk/kernel/syscalls/sys_chdir.c

    r301 r407  
    4141    process_t * process = this->process;
    4242
    43     // get pathname copy in kernel space
    44     error = hal_strcpy_from_uspace( kbuf, pathname, CONFIG_VFS_MAX_PATH_LENGTH );
    45 
    46     if( error )
     43    // check pathname length
     44    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
    4745    {
    48         printk("\n[ERROR] in %s : pathname too long for thread %x in process %x\n",
    49                __FUNCTION__ , this->trdid , process->pid );
     46        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
    5047        this->errno = ENFILE;
    5148        return -1;
    5249    }
     50
     51    // copy pathname in kernel space
     52    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    5353
    5454    // get cluster and local pointer on reference process
  • trunk/kernel/syscalls/sys_chmod.c

    r302 r407  
    4040    process_t * process = this->process;
    4141
    42     // get pathname copy in kernel space
    43     error = hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    44 
    45     if( error )
     42    // check pathname length
     43    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
    4644    {
    4745        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     
    4947        return -1;
    5048    }
     49
     50    // copy pathname in kernel space
     51    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    5152
    5253    // get cluster and local pointer on reference process
  • trunk/kernel/syscalls/sys_closedir.c

    r23 r407  
    2424#include <hal_types.h>
    2525#include <vfs.h>
     26#include <printk.h>
    2627#include <thread.h>
    27 #include <printk.h>
    2828#include <process.h>
     29#include <errno.h>
     30#include <syscalls.h>
     31#include <shared_syscalls.h>
    2932
    30 /////////////////////////////////////
    31 int sys_closedir ( uint32_t file_id )
     33///////////////////////////////
     34int sys_closedir ( DIR * dirp )
    3235{
    33         error_t        error;
    34         xptr_t         file_xp;   // extended pointer on searched directory file descriptor
    35 
    36         thread_t     * this     = CURRENT_THREAD;
    37         process_t    * process  = this->process;
    38 
    39     // check file_id argument
    40         if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    41         {
    42         printk("\n[ERROR] in %s : illegal file descriptor index %d\n",
    43                __FUNCTION__ , file_id );
    44         this->errno = EBADFD;
    45                 return -1;
    46         }
    47 
    48     // get extended pointer on remote file descriptor
    49     file_xp = process_fd_get_xptr( process , file_id );
    50 
    51     if( file_xp == XPTR_NULL )
    52     {
    53         printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
    54                __FUNCTION__ , file_id );
    55                 this->errno = EBADFD;
    56                 return -1;
    57     }
    58 
    59     // call relevant VFS function
    60         error  = vfs_close( file_xp , file_id );
    61 
    62         if( error )
    63         {
    64         printk("\n[ERROR] in %s : cannot close the directory = %d\n",
    65                __FUNCTION__ , file_id );
    66                 this->errno = error;
    67                 return -1;
    68         }
    69 
    70         return 0;
    71 
     36    printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__ );
     37    CURRENT_THREAD->errno = ENOMEM;
     38    return -1;
    7239}  // end sys_closedir()
  • trunk/kernel/syscalls/sys_creat.c

    r23 r407  
    2525#include <vfs.h>
    2626#include <syscalls.h>
     27#include <shared_syscalls.h>
    2728
    2829////////////////////////////////////
  • trunk/kernel/syscalls/sys_exec.c

    r406 r407  
    3838
    3939////////////////////////////////////////////////i//////////////////////////////////////
    40 // This static function is called by the sys_exec() function to register the .elf
    41 // pathname in the exec_info  structure, from a string stored in user space.
    42 ////////////////////////////////////////////////i//////////////////////////////////////
    43 // @ exec_info : pointer on the exec_info structure.
    44 // @ pathname  : string containing the path to the .elf file (user space).
    45 // return 0 if success / non-zero if one string too long, or too many strings.
    46 ///////////////////////////////////////////////////////////////////////////////////////
    47 static error_t process_exec_get_path( exec_info_t  * exec_info,
    48                                       char         * pathname )
    49 {
    50     error_t error;
    51 
    52     // copy string to exec_info
    53     error = hal_strcpy_from_uspace( &exec_info->path[0] , pathname ,
    54                                     CONFIG_VFS_MAX_PATH_LENGTH );
    55     if( error )
    56         return EINVAL;
    57 
    58     return 0;
    59 }
    60 
    61 ////////////////////////////////////////////////i//////////////////////////////////////
    6240// This static function is called twice by the sys_exec() function :
    6341// - to register the main() arguments (args) in the exec_info structure.
     
    7149// to store the (args) and (envs) strings are configuration parameters.
    7250///////////////////////////////////////////////////////////////////////////////////////
    73 // @ exec_info : pointer on the exec_info structure.
    74 // @ is_args   : true if called for (args) / false if called for (envs).
    75 // @ pointers  : array of pointers on the strings (in user space).
     51// @ exec_info   : pointer on the exec_info structure.
     52// @ is_args     : true if called for (args) / false if called for (envs).
     53// @ u_pointers  : array of pointers on the strings (in user space).
    7654// @ return 0 if success / non-zero if too many strings or no more memory.
    7755///////////////////////////////////////////////////////////////////////////////////////
     
    173151// This function build an exec_info_t structure containing all informations
    174152// required to create the new process descriptor and the associated thread.
    175 // It calls the static process_exec_get_path() and process_exec_get_strings() functions
    176 // to copy the .elf pathname, the main() arguments and the environment variables from
    177 // user buffers to the exec_info_t structure, and call the process_make_exec() function.
     153// It calls the process_exec_get_strings() functions to copy the main() arguments and
     154// the environment variables from user buffers to the exec_info_t structure, allocate
     155// and call the process_make_exec() function.
     156// Finally, it destroys the calling thread and process.
     157// TODO : the args & envs arguments are not supported yet : both must be NULL
    178158/////////////////////////////////////////////////////////////////////////////////////////
    179 int sys_exec( char  * filename,     // .elf file pathname
     159int sys_exec( char  * pathname,     // .elf file pathname
    180160              char ** args,         // process arguments
    181161              char ** envs )        // environment variables
    182162{
    183     exec_info_t  exec_info;         // structure to pass to process_make_exec()
    184     error_t      error;
    185     paddr_t      paddr;
    186 
     163    exec_info_t   exec_info;        // structure to pass to process_make_exec()
     164    error_t       error;
     165
     166        uint64_t      tm_start;
     167        uint64_t      tm_end;
     168
     169        tm_start = hal_get_cycles();
     170
     171    // get pointers on parent process and thread
    187172    thread_t   * this    = CURRENT_THREAD;
    188173    process_t  * process = this->process;
    189 
    190     // check argument fileme
    191     error = vmm_v2p_translate( false , filename , &paddr );
     174    pid_t        pid     = process->pid;
     175
     176exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / cycle %d\n",
     177__FUNCTION__, local_cxy, this->core->lid, pid, (uint32_t)hal_get_cycles() );
     178
     179sched_display( 0 );
     180
     181    // check pathname length
     182    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
     183    {
     184        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     185        this->errno = ENFILE;
     186        return -1;
     187    }
     188
     189    // copy pathname in exec_info structure (kernel space)
     190    hal_strcpy_from_uspace( exec_info.path , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
     191    // check args argument
     192    assert( (args == NULL) , __FUNCTION__ ,
     193    "args not supported yet\n" );
     194
     195    // check envs argument
     196    assert( (envs == NULL) , __FUNCTION__ ,
     197    "args not supported yet\n" );
     198
     199    // compute client_cxy (local cluster) and server_cxy (target cluster)
     200    cxy_t     cxy_server = CXY_FROM_PID( pid );
     201    cxy_t     cxy_client = local_cxy;
     202
     203    // register parent process in exec_info
     204    exec_info.parent_xp   = process->ref_xp;
     205
     206    // new process keep the parent process PID
     207    exec_info.keep_pid   = true;
     208
     209    // check and store args in exec_info structure if required
     210    if( args != NULL )
     211    {
     212        if( process_exec_get_strings( &exec_info , true , args ) )
     213        {
     214            printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ );
     215            this->errno = error;
     216            return -1;
     217        }
     218    }
     219
     220    // check and store envs in exec_info structure if required
     221    if( envs != NULL )
     222    {
     223        if( process_exec_get_strings( &exec_info , false , envs ) )
     224        {
     225            printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ );
     226            this->errno = error;
     227            return -1;
     228        }
     229    }
     230
     231    // call process_make_exec (local or remote)
     232    if( cxy_server == cxy_client )
     233    {
     234        error = process_make_exec( &exec_info );
     235    }
     236    else
     237    {
     238        rpc_process_exec_client( cxy_server , &exec_info , &error );
     239    }
    192240
    193241    if( error )
    194242    {
    195         printk("\n[ERROR] in %s : filename unmapped\n", __FUNCTION__ );
    196         this->errno = EINVAL;
    197         return -1;
    198     }
    199 
    200     // check argument fileme
    201     error = vmm_v2p_translate( false , args , &paddr );
    202 
    203     if( error )
    204     {
    205         printk("\n[ERROR] in %s : args unmapped\n", __FUNCTION__ );
    206         this->errno = EINVAL;
    207         return -1;
    208     }
    209 
    210     // check argument fileme
    211     error = vmm_v2p_translate( false , envs , &paddr );
    212 
    213     if( error )
    214     {
    215         printk("\n[ERROR] in %s : envs unmapped\n", __FUNCTION__ );
    216         this->errno = EINVAL;
    217         return -1;
    218     }
    219 
    220     // compute client_cxy (local cluster) and server_cxy (target cluster)
    221     cxy_t     cxy_server = CXY_FROM_PID( process->pid );
    222     cxy_t     cxy_client = local_cxy;
    223     bool_t    is_local   = (cxy_server == cxy_client);
    224 
    225     exec_dmsg("\n[DMSG] %s starts for process %x on core %d in cluster %x"
    226                  " / target_cluster = %x / cycle %d\n",
    227                  __FUNCTION__, process->pid , CURRENT_CORE->lid,
    228                  cxy_client, cxy_server, hal_get_cycles());
    229 
    230     // register reference parent process in exec_info
    231     exec_info.parent_xp   = process->ref_xp;
    232 
    233     // check pathname and store it in exec_info structure
    234     error = process_exec_get_path( &exec_info , filename );
    235 
    236     if ( error )
    237     {
    238         printk("\n[ERROR] in %s : elf pathname too long\n", __FUNCTION__ );
     243        printk("\n[ERROR] in %s : cannot create new process %x in cluster %x\n",
     244        __FUNCTION__, pid, cxy_server );
    239245        this->errno = error;
    240246        return -1;
    241247    }
    242248
    243     // check and store args in exec_info structure
    244     error = process_exec_get_strings( &exec_info , true , args );
    245 
    246     if( error )
    247     {
    248         printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ );
    249         this->errno = error;
    250         return -1;
    251     }
    252 
    253     // check and store envs in exec_info structure
    254     error = process_exec_get_strings( &exec_info , false , envs );
    255 
    256     if( error )
    257     {
    258         printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ );
    259         this->errno = error;
    260         return -1;
    261     }
    262 
    263     exec_dmsg("\n[DMSG] %s starts exec for process %x at cycle %d\n",
    264               __FUNCTION__, process->pid, hal_get_cycles() );
    265 
    266     if( is_local )  error = process_make_exec( &exec_info );
    267     else            rpc_process_exec_client( cxy_server , &exec_info , &error );
    268 
    269     if( error )
    270     {
    271         printk("\n[ERROR] in %s : cannot create new process %x\n",
    272                __FUNCTION__ , process->pid );
    273         this->errno = error;
    274         return -1;
    275     }
    276 
    277     exec_dmsg("\n[DMSG] %s completes exec for process %x at cycle %d\n",
    278               __FUNCTION__, process->pid , hal_get_cycles() );
    279 
    280     // delete the calling thread an process
    281     thread_kill( CURRENT_THREAD );
    282     process_kill( CURRENT_THREAD->process );
     249    // FIXME delete the local process descriptor
     250    // process_kill( process );
     251
     252    tm_end = hal_get_cycles();
     253
     254exec_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x / cycle %d\n"
     255"     pathname = %s / cost = %d\n",
     256__FUNCTION__, local_cxy, this->core->lid, pid, (uint32_t)tm_start,
     257exec_info.path , (uint32_t)(tm_end - tm_start) );
    283258
    284259    return 0;
  • trunk/kernel/syscalls/sys_fork.c

    r406 r407  
    2424#include <kernel_config.h>
    2525#include <hal_types.h>
     26#include <hal_context.h>
     27#include <hal_switch.h>
    2628#include <hal_atomic.h>
    2729#include <errno.h>
     
    4547    pid_t                child_pid;       // child process identifier
    4648        thread_t           * child_thread;    // pointer on child main thread descriptor
    47     trdid_t              child_trdid;     // child main thread identifier
    48     lid_t                child_core_lid;  // core local index for the child main thread
    49     cxy_t                target_cxy;      // final target cluster for forked child process
     49    cxy_t                target_cxy;      // target cluster for forked child process
    5050        error_t              error;
     51
     52        uint64_t      tm_start;
     53        uint64_t      tm_end;
     54
     55        tm_start = hal_get_cycles();
    5156
    5257    // get pointers on parent process and thread
     
    5560    parent_pid     = parent_process->pid;
    5661
     62fork_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / cycle %d\n",
     63__FUNCTION__ , local_cxy , parent_thread->core->lid , parent_pid , (uint32_t)tm_start );
     64
    5765    // check parent process children number
    5866        if( hal_atomic_add( &parent_process->children_nr , 1 ) >= CONFIG_PROCESS_MAX_CHILDREN )
     
    6169            hal_atomic_add ( &parent_process->children_nr , -1 );
    6270        return EAGAIN;
    63         }
    64 
    65         fork_dmsg("\n[DMSG] %s : enters for process %d at cycle [%d]\n",
    66                   __FUNCTION__, parent_process->pid, hal_get_cycles());
    67 
    68     // save FPU state in fpu_context if parent process is FPU owner
    69     // because we want the child process to share the FPU context
    70         if( CURRENT_CORE->fpu_owner == parent_thread )
    71         {
    72                 hal_fpu_context_save( parent_thread );
    73                 fork_dmsg("\n[DMSG] %s : save FPU\n", __FUNCTION__);
    7471        }
    7572
     
    9592        }
    9693
    97         fork_dmsg("INFO : %s select target_cluster = %x\n",
    98               __FUNCTION__ , target_cxy );
     94//printk("\n[DBG] %s : core[%x,%d] for process %x selects target_cluster = %x\n",
     95//__FUNCTION__ , local_cxy , parent_thread->core->lid , parent_pid , target_cxy );
    9996
    10097    // allocates memory in local cluster for the child process descriptor
     
    127124
    128125    // initialize and register the child process descriptor
    129     process_reference_init( child_process , child_pid , parent_pid );
    130 
    131         fork_dmsg("\n[DMSG] : %s created child process : pid = %x / ppid = %x\n",
    132               __FUNCTION__, child_pid , parent_pid );
     126    process_reference_init( child_process , child_pid , XPTR(local_cxy, parent_process) );
    133127
    134128    // initialises child process standard files structures
     
    148142                            XPTR( local_cxy , &parent_process->fd_array ) );
    149143
    150         fork_dmsg("\n[DMSG] %s : duplicated child process from parent process\n",
    151                   __FUNCTION__ );
    152 
    153     // replicates virtual memory manager
     144//printk("\n[DBG] %s : core[%x,%d] for process %x created child process %x\n",
     145//__FUNCTION__ , local_cxy , parent_thread->core->lid , parent_pid , child_pid );
     146
     147    // replicate VMM
    154148        error = vmm_copy( child_process , parent_process );
    155149
     
    162156    }
    163157 
    164         fork_dmsg("\n[DMSG] %s : parent vmm duplicated in child process\n", __FUNCTION__ );
    165 
    166     // create child main thread descriptor in local cluster
    167     error = thread_user_fork( parent_process , &child_thread );
    168 
     158//printk("\n[DBG] %s : core[%x,%d] for process %x duplicated vmm in child process\n",
     159//__FUNCTION__ , local_cxy , parent_thread->core->lid , parent_pid );
     160//vmm_display( parent_process , true );
     161//vmm_display( child_process , true );
     162
     163    // create child main thread in local cluster
     164    error = thread_user_fork( child_process,
     165                              parent_thread->u_stack_size,
     166                              parent_thread->u_stack_base,
     167                              &child_thread );
    169168        if( error )
    170169    {
    171             printk("\n[ERROR] in %s : cannot duplicate thread\n", __FUNCTION__ );
     170            printk("\n[ERROR] in %s : cannot duplicate main thread\n", __FUNCTION__ );
    172171            hal_atomic_add( &parent_process->children_nr , -1 );
    173172        process_destroy( child_process );
     
    175174    }
    176175
    177     // register child thread in child process, and get a TRDID
    178     spinlock_lock( &child_process->th_lock );
    179     error = process_register_thread( child_process, child_thread , &child_trdid );
    180     spinlock_unlock( &child_process->th_lock );
    181 
    182     if( error )
    183     {
    184         printk("\n[ERROR] in %s : cannot register thread\n", __FUNCTION__ );
    185             hal_atomic_add ( &parent_process->children_nr , -1 );
    186         thread_destroy( child_thread );
    187         process_destroy( child_process );
    188         return EAGAIN;
    189     }
    190  
    191     // get a local core to execute child thread
    192     child_core_lid = cluster_select_local_core();
    193 
    194         // Update child thread descriptor
    195         child_thread->core    = &LOCAL_CLUSTER->core_tbl[child_core_lid];
    196         child_thread->process = child_process;
    197     child_thread->trdid   = child_trdid;
    198 
    199         fork_dmsg("\n[DMSG] %s : initialised child main thread\n", __FUNCTION__ );
    200 
    201     // register local child thread into local child process th_tbl[]
    202     // we don't use the th_lock because there is no concurrent access
    203     ltid_t ltid = LTID_FROM_TRDID( child_trdid );
    204         child_process->th_tbl[ltid] = child_thread;
    205         child_process->th_nr = 1;
    206 
    207     // register child thread in scheduler
    208         sched_register_thread( child_thread->core , child_thread );
    209  
    210         fork_dmsg("\n[DMSG] %s : registered main thread in scheduler\n", __FUNCTION__);
     176//printk("\n[DBG] %s : core[%x,%d] initialised child main thread\n",
     177//__FUNCTION__ , local_cxy , parent_thread->core->lid );
    211178
    212179        // update DQDT for the child thread
    213180    dqdt_local_update_threads( 1 );
    214181
    215         fork_dmsg("\n[DMSG] %s : completed / parent pid = %x / child pid = %x / at cycle [%d]\n",
    216                   __FUNCTION__, parent_process->pid, child_process->pid, hal_get_cycles() );
    217 
    218         return child_process->pid;
     182    // set child_thread FPU_context from parent_thread register values
     183    // only when the parent process is the FPU owner
     184        if( CURRENT_THREAD->core->fpu_owner == parent_thread )
     185        {
     186                hal_fpu_context_save( child_thread->fpu_context );
     187        }
     188
     189    // set child_thread CPU context from parent_thread register values
     190    hal_do_cpu_save( child_thread->cpu_context,
     191                     child_thread,
     192                     (int)((intptr_t)child_thread - (intptr_t)parent_thread) );
     193
     194
     195    // from this point, both parent and child threads execute the following code
     196    // but child execute it only when it has been unblocked by its parent
     197
     198    thread_t * current = CURRENT_THREAD;
     199
     200    if( current == parent_thread )
     201    {
     202        // parent_thread unblock child_thread
     203        thread_unblock( XPTR( local_cxy , child_thread ) , THREAD_BLOCKED_GLOBAL );
     204
     205        tm_end = hal_get_cycles();
     206
     207fork_dmsg("\n[DBG] %s : core[%x,%d] parent_process %x exit / cycle %d\n"
     208"     child_process %x / child_thread = %x / cost = %d\n",
     209__FUNCTION__, local_cxy, parent_thread->core->lid,  parent_pid, (uint32_t)tm_start,
     210child_pid, child_thread->trdid , (uint32_t)(tm_end - tm_start) );
     211
     212        return child_pid;
     213    }
     214        else  // current == child_thread
     215    {
     216        assert( (current == child_thread) , __FUNCTION__ ,
     217        "current thread %x is not the child thread %x\n", current , child_thread );
     218
     219fork_dmsg("\n[DBG] %s : core[%x,%d] child process %x exit / cycle %d\n",
     220__FUNCTION__, local_cxy, parent_thread->core->lid, child_pid, (uint32_t)hal_get_cycles() );
     221
     222        return 0;
     223    }
    219224
    220225}  // end sys_fork()
  • trunk/kernel/syscalls/sys_get_cycle.c

    r405 r407  
    11/*
    2  * sys_clock: get calling core cycles count
     2 * sys_get_cycle.c - get calling core cycles count.
    33 *
    44 * Author    Alain Greiner (2016,2017)
     
    3232#include <printk.h>
    3333
    34 //////////////////////////////////
    35 int sys_clock (uint64_t * cycles )
     34//////////////////////////////////////
     35int sys_get_cycle ( uint64_t * cycle )
    3636{
    3737        error_t   error;
    3838    paddr_t   paddr;
    39         uint64_t  k_cycles;
     39        uint64_t  k_cycle;
    4040
    4141    thread_t  * this    = CURRENT_THREAD;
     
    4343
    4444    // check buffer in user space
    45     error = vmm_v2p_translate( false , cycles , &paddr );
     45    error = vmm_v2p_translate( false , cycle , &paddr );
    4646
    4747        if( error )
     
    5454
    5555    // call relevant core function
    56         k_cycles = hal_get_cycles();
     56        k_cycle = hal_get_cycles();
    5757
    5858    // copy to user space
    59         hal_copy_to_uspace( cycles , &k_cycles , sizeof(uint64_t) );
     59        hal_copy_to_uspace( cycle , &k_cycle , sizeof(uint64_t) );
    6060
    6161        return 0;
    6262
    63 }  // end sys_clock()
     63}  // end sys_get_cycle()
  • trunk/kernel/syscalls/sys_mkdir.c

    r303 r407  
    11/*
    2  * sys_mkdir.c - Create a new directory
     2 * sys_mkdir.c - Create a new directory in file system.
    33 *
    44 * Author    Alain Greiner (2016,2017)
     
    5050    }
    5151
    52     // get pathname copy in kernel space
    53     error = hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    54 
    55     if( error )
     52    // check pathname length
     53    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
    5654    {
    5755        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     
    5957        return -1;
    6058    }
     59
     60    // copy pathname in kernel space
     61    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    6162
    6263    // get cluster and local pointer on reference process
  • trunk/kernel/syscalls/sys_mkfifo.c

    r304 r407  
    4848    }
    4949
    50     // get pathname copy in kernel space
    51     error = hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    52 
    53     if( error )
     50    // check pathname length
     51    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
    5452    {
    5553        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     
    5755        return -1;
    5856    }
     57
     58    // copy pathname in kernel space
     59    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    5960
    6061    // get cluster and local pointer on reference process
  • trunk/kernel/syscalls/sys_mmap.c

    r23 r407  
    2424
    2525#include <hal_types.h>
     26#include <hal_uspace.h>
     27#include <shared_syscalls.h>
    2628#include <errno.h>
    2729#include <thread.h>
    2830#include <printk.h>
     31#include <mapper.h>
    2932#include <vfs.h>
    3033#include <process.h>
    3134#include <vmm.h>
    3235
    33 ///////////////////////////////////
     36//////////////////////////////////
    3437int sys_mmap( mmap_attr_t * attr )
    3538{
    36     printk("\n[WARNING] function %s not implemented\n", __FUNCTION__ );
    37     return 0;
    38 /*   
    39         error_t err;
    40         uint_t count;
    41         struct thread_s *this;
    42         struct process_s *process;
    43         struct vfs_file_s *file;
    44         mmap_attr_t attr;
    45         size_t isize;
    46         int retval;
     39    vseg_t      * vseg;
     40    cxy_t         vseg_cxy;
     41    vseg_type_t   vseg_type;
     42    mmap_attr_t   k_attr;       // attributes copy in kernel space
     43    xptr_t        mapper_xp;
     44    error_t       error;
     45    paddr_t       paddr;        // unused, but required for user space checking
     46
     47        uint64_t      tm_start;
     48        uint64_t      tm_end;
     49
     50        tm_start = hal_get_cycles();
     51
     52        thread_t    * this    = CURRENT_THREAD;
     53        process_t   * process = this->process;
     54
     55    // check arguments in user space
     56    error = vmm_v2p_translate( false , attr , &paddr );
     57
     58    if ( error )
     59    {
     60        printk("\n[ERROR] in %s : arguments not in used space = %x\n",
     61        __FUNCTION__ , (intptr_t)attr );
     62                this->errno = EINVAL;
     63                return -1;
     64    }
     65
     66    // copy arguments from uspace
     67    hal_copy_from_uspace( &k_attr , attr , sizeof(mmap_attr_t) );
     68
     69    // get fdid, offset, and length arguments
     70    uint32_t fdid   = k_attr.fdid;
     71    uint32_t offset = k_attr.offset;
     72    uint32_t length = k_attr.length;
     73
     74    // get flags
     75    bool_t     map_fixed   = ( (k_attr.flags & MAP_FIXED)   != 0 );
     76    bool_t     map_anon    = ( (k_attr.flags & MAP_ANON)    != 0 );
     77    bool_t     map_remote  = ( (k_attr.flags & MAP_REMOTE)  != 0 );
     78    bool_t     map_shared  = ( (k_attr.flags & MAP_SHARED)  != 0 );
     79    bool_t     map_private = ( (k_attr.flags & MAP_PRIVATE) != 0 );
     80
     81    // MAP_FIXED not supported
     82    if( map_fixed )
     83    {
     84        printk("\n[ERROR] in %s : MAP_FIXED not supported\n", __FUNCTION__ );
     85        this->errno = EINVAL;
     86        return -1;
     87    }
     88
     89    if( map_shared == map_private )
     90    {
     91        printk("\n[ERROR] in %s : MAP_SHARED xor MAP_PRIVATE\n", __FUNCTION__ );
     92        this->errno = EINVAL;
     93        return -1;
     94    }
     95
     96    // FIXME handle Copy_On_Write for MAP_PRIVATE...
     97
     98    // get access rigths
     99    bool_t     prot_read   = ( (k_attr.prot & PROT_READ )   != 0 );
     100    bool_t     prot_write  = ( (k_attr.prot & PROT_WRITE)   != 0 );
     101
     102    // test mmap type : can be FILE / ANON / REMOTE
     103
     104    if( (map_anon == false) && (map_remote == false) )   // FILE
     105    {
     106            // FIXME: handle concurent delete of file by another thread closing it
     107
     108                if( fdid >= CONFIG_PROCESS_FILE_MAX_NR )
     109                {
     110                        printk("\n[ERROR] in %s: bad file descriptor = %d\n", __FUNCTION__ , fdid );
     111            this->errno = EBADFD;
     112            return -1;
     113        }
     114
     115        // get extended pointer on file descriptor
     116        xptr_t file_xp = process_fd_get_xptr( process , fdid );
     117
     118        if( file_xp == XPTR_NULL )
     119        {
     120                        printk("\n[ERROR] in %s: file %d not found\n", __FUNCTION__ , fdid );
     121            this->errno = EBADFD;
     122            return -1;
     123        }
     124
     125        // get file cluster and local pointer
     126        cxy_t        file_cxy = GET_CXY( file_xp );
     127        vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     128
     129        // get inode pointer, mapper pointer and file attributes
     130        vfs_inode_t * inode_ptr  = hal_remote_lpt(XPTR(file_cxy , &file_ptr->inode ));
     131        uint32_t      file_attr  = hal_remote_lw (XPTR(file_cxy , &file_ptr->attr  ));
     132        mapper_t    * mapper_ptr = hal_remote_lpt(XPTR(file_cxy , &file_ptr->mapper));
     133
     134        // get file size
     135                uint32_t size = hal_remote_lw( XPTR( file_cxy , &inode_ptr->size ) );
     136
     137        // chek offset and length arguments
     138                if( (offset + length) > size)
     139                {
     140                        printk("\n[ERROR] in %s: offset (%d) + len (%d) >= file's size (%d)\n",
     141                        __FUNCTION__, k_attr.offset, k_attr.length, size );
     142            this->errno = ERANGE;
     143            return -1;
     144                }
     145
     146        // check access rights
     147                if( (prot_read  && !(file_attr & FD_ATTR_READ_ENABLE)) ||
     148                    (prot_write && !(file_attr & FD_ATTR_WRITE_ENABLE)) )
     149                {
     150                        printk("\n[ERROR] in %s: prot = %x / file_attr = %x)\n",
     151                        __FUNCTION__ , k_attr.prot , file_attr );
     152                        this->errno = EACCES;
     153                        return -1;
     154                }
     155
     156                // increment file refcount
     157                vfs_file_count_up( file_xp );
     158
     159        mapper_xp = XPTR( file_cxy , mapper_ptr );
     160        vseg_type = VSEG_TYPE_FILE;
     161        vseg_cxy  = file_cxy;
     162    }
     163    else                                                // ANON or REMOTE
     164    {
     165        // no mapper for ANON or REMOTE
     166        mapper_xp = XPTR_NULL;
     167
     168        if( map_anon )
     169        {
     170            vseg_type = VSEG_TYPE_ANON;
     171            vseg_cxy  = local_cxy;
     172        }
     173        else
     174        {
     175            vseg_type = VSEG_TYPE_REMOTE;
     176            vseg_cxy  = k_attr.fdid;
    47177 
    48         this = current_thread;
    49         process = this->process;
    50         err  = EINVAL;
    51         file = NULL;
    52 
    53         if((err = cpu_copy_from_uspace(&attr, attr, sizeof(mmap_attr_t))))
    54         {
    55                 printk(INFO, "%s: failed, copying from uspace @%x\n",
    56                        __FUNCTION__,
    57                        attr);
    58 
    59                 this->info.errno = EFAULT;
    60                 return (int)VM_FAILED;
    61         }
    62 
    63         if((attr.flags  & VM_REG_HEAP)                     ||
    64            ((attr.flags & VM_REG_PVSH) == VM_REG_PVSH)     ||
    65            ((attr.flags & VM_REG_PVSH) == 0)               ||
    66            (attr.length == 0)                              ||
    67            (attr.offset & PMM_PAGE_MASK)                   ||
    68            ((attr.addr != NULL) && (((uint_t)attr.addr & PMM_PAGE_MASK)          ||
    69                                 (NOT_IN_USPACE(attr.length + (uint_t)attr.addr)) ||
    70                                 (NOT_IN_USPACE((uint_t)attr.addr)) )))
    71         {
    72                 printk(INFO, "%s: failed, we don't like flags (%x), length (%d), or addr (%x)\n",
    73                        __FUNCTION__,
    74                        attr.flags,
    75                        attr.length,
    76                        attr.addr);
    77      
    78                 this->info.errno = EINVAL;
    79                 return (int)VM_FAILED;
    80         }
    81    
    82         if(attr.flags & VM_REG_ANON)
    83         {
    84                 attr.offset = 0;
    85                 attr.addr   = (attr.flags & VM_REG_FIXED) ? attr.addr : NULL;
    86         }
    87         else
    88         {     
    89                 // FIXME: possible concurent delete of file from another bugy thread closing it
    90                 if((attr.fd >= CONFIG_TASK_FILE_MAX_NR) || (process_fd_lookup(process, attr.fd, &file)))
    91                 {
    92                         printk(INFO, "%s: failed, bad file descriptor (%d)\n",
    93                                __FUNCTION__,
    94                                attr.fd);
    95 
    96                         this->info.errno = EBADFD;
    97                         return (int)VM_FAILED;
    98                 }
    99      
    100                 //atomic_add(&file->f_count, 1);
    101                 vfs_file_up(file);//FIXME coalsce access to remote node info
    102      
    103                 //FIXME: does we really to get the size...
    104                 isize = vfs_inode_size_get_remote(file->f_inode.ptr, file->f_inode.cid);
    105                 if((attr.offset + attr.length) > isize)
    106                 {
    107                         printk(INFO, "%s: failed, offset (%d) + len (%d) >= file's size (%d)\n",
    108                                __FUNCTION__,
    109                                attr.offset,
    110                                attr.length,
    111                                isize);
    112 
    113                         this->info.errno = ERANGE;
    114                         goto SYS_MMAP_FILE_ERR;
    115                 }
    116 
    117                 if(((attr.prot & VM_REG_RD) && !(VFS_IS(file->f_flags, VFS_O_RDONLY)))   ||
    118                    ((attr.prot & VM_REG_WR) && !(VFS_IS(file->f_flags, VFS_O_WRONLY)))   ||
    119                    ((attr.prot & VM_REG_WR) && (VFS_IS(file->f_flags, VFS_O_APPEND))))//    ||
    120                         //(!(attr.prot & VM_REG_RD) && (attr.flags & VM_REG_PRIVATE)))
    121                 {
    122                         printk(INFO, "%s: failed, EACCES prot (%x), f_flags (%x)\n",
    123                                __FUNCTION__,
    124                                attr.prot,
    125                                file->f_flags);
    126 
    127                         this->info.errno = EACCES;
    128                         goto SYS_MMAP_FILE_ERR;
    129                 }
    130         }
    131 
    132         retval = (int) vmm_mmap(process,
    133                                 file,
    134                                 attr.addr,
    135                                 attr.length,
    136                                 attr.prot,
    137                                 attr.flags,
    138                                 attr.offset);
    139    
    140         if((retval != (int)VM_FAILED) || (attr.flags & VM_REG_ANON))
    141                 return retval;
    142 
    143 SYS_MMAP_FILE_ERR:
    144         printk(INFO, "%s: Failed, Droping file count \n",
    145                __FUNCTION__);
    146    
    147         vfs_close( file , &count );
    148 
    149         if(count == 1) process_fd_put( process , attr.fd );
    150 
    151         return (int)VM_FAILED;
    152 */
     178            if( cluster_is_undefined( vseg_cxy ) )
     179            {
     180                printk("\n[ERROR] in %s : illegal cxy for MAP_REMOTE\n", __FUNCTION__ );
     181                this->errno = EINVAL;
     182                return -1;
     183            }
     184        }
     185    }
     186
     187    // get reference process cluster and local pointer
     188    xptr_t      ref_xp  = process->ref_xp;
     189    cxy_t       ref_cxy = GET_CXY( ref_xp );
     190    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     191
     192    // create the vseg in reference cluster
     193    if( local_cxy == ref_cxy )
     194    {
     195        vseg = vmm_create_vseg( process,
     196                                vseg_type,
     197                                0,               // base address unused for mmap()
     198                                length,
     199                                offset,
     200                                0,               // file_size unused for mmap()
     201                                mapper_xp,
     202                                vseg_cxy );
     203    }
     204    else
     205    {
     206        rpc_vmm_create_vseg_client( ref_cxy,
     207                                    ref_ptr,
     208                                    vseg_type,
     209                                    0,            // base address unused for mmap()
     210                                    length,
     211                                    offset,
     212                                    0,            // file size unused for mmap()
     213                                    mapper_xp,
     214                                    vseg_cxy,
     215                                    &vseg );
     216    }
     217   
     218    if( vseg == NULL )
     219    {
     220        printk("\n[ERROR] in %s : cannot create vseg\n", __FUNCTION__ );
     221        this->errno = ENOMEM;
     222        return -1;
     223    }
     224
     225    // copy vseg base address to user space
     226    hal_copy_to_uspace( &attr->addr , &vseg->min , sizeof(intptr_t) );
     227
     228    tm_end = hal_get_cycles();
     229
     230syscall_dmsg("\n[DBG] %s : core[%x,%d] created vseg %s in cluster %x / cycle %d\n"
     231"      base = %x / length = %x / cost = %d\n",
     232__FUNCTION__, local_cxy , this->core->lid , vseg_type_str(vseg->type) ,
     233vseg->cxy , (uint32_t)tm_start , vseg->min , length , (uint32_t)(tm_end - tm_start) );
     234
     235        return 0;
     236
    153237}  // end sys_mmap()
     238
  • trunk/kernel/syscalls/sys_open.c

    r305 r407  
    5555    }
    5656
    57     // get pathname copy in kernel space
    58     error = hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    59 
    60     if( error )
     57    // check pathname length
     58    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
    6159    {
    6260        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     
    6563    }
    6664
     65    // copy pathname in kernel space
     66    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
     67
    6768    // get cluster and local pointer on reference process
    6869    xptr_t      ref_xp  = process->ref_xp;
     
    7071    cxy_t       ref_cxy = GET_CXY( ref_xp );
    7172
    72     // get extended pointer on cwd inode
    73     xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
    74 
    7573    // get the cwd lock in read mode from reference process
    7674    remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
    7775
    7876    // call the relevant VFS function
    79     error = vfs_open( cwd_xp,
     77    error = vfs_open( process,
    8078                      kbuf,
    8179                      flags,
  • trunk/kernel/syscalls/sys_opendir.c

    r23 r407  
    2323
    2424#include <hal_types.h>
     25#include <thread.h>
     26#include <process.h>
     27#include <printk.h>
     28#include <errno.h>
    2529#include <vfs.h>
    2630#include <syscalls.h>
     31#include <shared_syscalls.h>
    2732
    2833///////////////////////////////////
    29 int sys_opendir ( char * pathname )
     34int sys_opendir ( char *  pathname,
     35                  DIR  ** dirp )
    3036{
    31         uint32_t   mode  = 0;
    32     uint32_t   flags = O_DIR;
    33 
    34     return sys_open( pathname , flags , mode );
    35 }
     37    printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__ );
     38    CURRENT_THREAD->errno = ENOMEM;
     39    return -1;
     40}  // end sys opendir()
  • trunk/kernel/syscalls/sys_pipe.c

    r23 r407  
    3636    this->errno = ENOSYS;
    3737    return -1;
    38 
    3938}
  • trunk/kernel/syscalls/sys_read.c

    r313 r407  
    3333#include <process.h>
    3434
    35 /* TODO: user page(s) need to be locked  [AG] */
     35// TODO: concurrent user page(s) munmap need to be handled [AG]
     36
     37// instrumentation
     38extern uint32_t enter_sys_read;
     39extern uint32_t enter_devfs_move;
     40extern uint32_t enter_txt_read;
     41extern uint32_t enter_chdev_cmd;
     42extern uint32_t enter_chdev_server;
     43extern uint32_t enter_tty_cmd;
     44extern uint32_t enter_tty_isr;
     45extern uint32_t exit_tty_isr;
     46extern uint32_t exit_tty_cmd;
     47extern uint32_t exit_chdev_server;
     48extern uint32_t exit_chdev_cmd;
     49extern uint32_t exit_txt_read;
     50extern uint32_t exit_devfs_move;
     51extern uint32_t exit_sys_read;
     52
    3653
    3754/////////////////////////////////
    3855int sys_read( uint32_t   file_id,
    39               void     * buf,
     56              void     * vaddr,
    4057              uint32_t   count )
    4158{
     
    4360    paddr_t      paddr;       // required for user space checking
    4461        xptr_t       file_xp;     // remote file extended pointer
     62    uint32_t     nbytes;      // number of bytes actually read
     63
     64        uint32_t     tm_start;
     65        uint32_t     tm_end;
     66
     67        tm_start = hal_get_cycles();
     68
     69#if CONFIG_READ_START
     70enter_sys_read = tm_start;
     71#endif
    4572
    4673        thread_t  *  this    = CURRENT_THREAD;
     
    5178        {
    5279        printk("\n[ERROR] in %s : illegal file descriptor index = %d\n",
    53                __FUNCTION__ , file_id );
     80        __FUNCTION__ , file_id );
    5481                this->errno = EBADFD;
    5582                return -1;
     
    5784
    5885    // check user buffer in user space
    59     error = vmm_v2p_translate( false , buf , &paddr );
     86    error = vmm_v2p_translate( false , vaddr , &paddr );
    6087
    6188    if ( error )
    6289    {
    6390        printk("\n[ERROR] in %s : user buffer unmapped = %x\n",
    64                __FUNCTION__ , (intptr_t)buf );
     91        __FUNCTION__ , (intptr_t)vaddr );
    6592                this->errno = EINVAL;
    6693                return -1;
     
    7299    if( file_xp == XPTR_NULL )
    73100    {
    74         printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
    75                __FUNCTION__ , file_id );
     101        printk("\n[ERROR] in %s : undefined file descriptor index = %d in process %x\n",
     102        __FUNCTION__ , file_id , process->pid );
    76103        this->errno = EBADFD;
    77104        return -1;
     
    86113    if( (attr & FD_ATTR_READ_ENABLE) == 0 )
    87114        {
    88         printk("\n[ERROR] in %s : file %d not readable\n",
    89                __FUNCTION__ , file_id );
     115        printk("\n[ERROR] in %s : file %d not readable in process %x\n",
     116        __FUNCTION__ , file_id , process->pid );
    90117                this->errno = EBADFD;
    91118                return -1;
    92119        }
    93120   
    94     // transfer count bytes directly from mapper to user buffer
    95     error = vfs_user_move( true,               // to_buffer
    96                            file_xp ,
    97                            buf,
    98                            count );
     121    // get file type
     122    vfs_inode_type_t type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type ) );
    99123
    100     if( error )
     124    // action depend on file type
     125    if( type == INODE_TYPE_FILE )      // transfer count bytes from file mapper
    101126    {
    102         printk("\n[ERROR] in %s cannot read data from file %d\n",
    103                __FUNCTION__ , file_id );
     127        nbytes = vfs_user_move( true,               // from mapper to buffer
     128                                file_xp,
     129                                vaddr,
     130                                count );
     131    }
     132    else if( type == INODE_TYPE_DEV )  // transfer count bytes from device
     133    {
     134        nbytes = devfs_user_move( true,             // from device to buffer
     135                                  file_xp,
     136                                  vaddr,
     137                                  count );
     138    }
     139    else
     140    {
     141        nbytes = 0;
     142        panic("file type %d non supported yet", type );
     143    }
     144
     145    if( nbytes != count )
     146    {
     147        printk("\n[ERROR] in %s cannot read data from file %d in process %x\n",
     148        __FUNCTION__ , file_id , process->pid );
    104149        this->errno = error;
    105150        return -1;
     
    108153    hal_fence();
    109154
    110         return 0;
     155    tm_end = hal_get_cycles();
     156
     157#if CONFIG_READ_DEBUG
     158exit_sys_read = tm_end;
     159
     160printk("\n@@@@@@@@@@@@ timing ro read character %c\n"
     161" - enter_sys_read     = %d / delta %d\n"
     162" - enter_devfs_move   = %d / delta %d\n"
     163" - enter_txt_read     = %d / delta %d\n"
     164" - enter_chdev_cmd    = %d / delta %d\n"
     165" - enter_chdev_server = %d / delta %d\n"
     166" - enter_tty_cmd      = %d / delta %d\n"
     167" - enter_tty_isr      = %d / delta %d\n"
     168" - exit_tty_isr       = %d / delta %d\n"
     169" - exit_tty_cmd       = %d / delta %d\n"
     170" - exit_chdev_server  = %d / delta %d\n"
     171" - exit_chdev_cmd     = %d / delta %d\n"
     172" - exit_txt_read      = %d / delta %d\n"
     173" - exit_devfs_move    = %d / delta %d\n"
     174" - exit_sys_read      = %d / delta %d\n",
     175*((char *)(intptr_t)paddr) ,
     176enter_sys_read     , 0 ,
     177enter_devfs_move   , enter_devfs_move   - enter_sys_read     ,
     178enter_txt_read     , enter_txt_read     - enter_devfs_move   ,
     179enter_chdev_cmd    , enter_chdev_cmd    - enter_txt_read     ,
     180enter_chdev_server , enter_chdev_server - enter_chdev_cmd    ,
     181enter_tty_cmd      , enter_tty_cmd      - enter_chdev_server ,
     182enter_tty_isr      , enter_tty_isr      - enter_tty_cmd      ,
     183exit_tty_isr       , exit_tty_isr       - enter_tty_isr      ,
     184exit_tty_cmd       , exit_tty_cmd       - exit_tty_isr       ,
     185exit_chdev_server  , exit_chdev_server  - exit_tty_cmd       ,
     186exit_chdev_cmd     , exit_chdev_cmd     - exit_chdev_server  ,
     187exit_txt_read      , exit_txt_read      - exit_chdev_cmd     ,
     188exit_devfs_move    , exit_devfs_move    - exit_txt_read      ,
     189exit_sys_read      , exit_sys_read      - exit_devfs_move    );
     190#endif
     191
     192syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / nbytes = %d / cycle %d\n"
     193" first byte = %c / file_id = %d / cost = %d\n",
     194__FUNCTION__ , local_cxy , this->core->lid , this->trdid , nbytes , tm_start ,
     195*((char *)(intptr_t)paddr) , file_id , tm_end - tm_start );
     196 
     197        return nbytes;
    111198
    112199}  // end sys_read()
  • trunk/kernel/syscalls/sys_readdir.c

    r23 r407  
    3131#include <process.h>
    3232#include <syscalls.h>
     33#include <shared_syscalls.h>
    3334
    34 //////////////////////////////////////////
    35 int sys_readdir ( uint32_t       file_id,
    36                   vfs_dirent_t * dirent )
     35///////////////////////////////////////
     36int sys_readdir( DIR            * dirp,
     37                 struct dirent ** dentp )
    3738{
    38         error_t        error;
    39     paddr_t        paddr;
    40         xptr_t         file_xp;    // extended pointer on searched directory file descriptor
    41     vfs_dirent_t   k_dirent;   // kernel copy of dirent
    42 
    43         thread_t     * this     = CURRENT_THREAD;
    44         process_t    * process  = this->process;
    45 
    46     // check file_id argument
    47         if( file_id >= CONFIG_PROCESS_FILE_MAX_NR )
    48         {
    49         printk("\n[ERROR] in %s : illegal file descriptor index\n", __FUNCTION__ );
    50         this->errno = EBADFD;
    51                 return -1;
    52         }
    53 
    54     // check dirent structure in user space
    55     error = vmm_v2p_translate( false , dirent , &paddr );
    56 
    57     if ( error )
    58     {
    59         printk("\n[ERROR] in %s : user buffer for dirent unmapped = %x\n",
    60                __FUNCTION__ , (intptr_t)dirent );
    61                 this->errno = EFAULT;
    62                 return -1;
    63     }
    64 
    65     // get extended pointer on remote file descriptor
    66     file_xp = process_fd_get_xptr( process , file_id );
    67 
    68     if( file_xp == XPTR_NULL )
    69     {
    70         printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
    71                __FUNCTION__ , file_id );
    72             this->errno = EBADFD;
    73         return -1;
    74     }
    75  
    76     // call the relevant VFS function
    77         error = vfs_readdir( file_xp , &k_dirent );
    78 
    79         if( error )
    80         {
    81         printk("\n[ERROR] in %s : cannot access directory %d\n",
    82                __FUNCTION__ , file_id );
    83                 this->errno = error;
    84                 return -1;
    85         }
    86    
    87     // copy dirent to user space
    88     hal_copy_to_uspace( dirent , &k_dirent , sizeof(vfs_dirent_t) );
    89 
    90         return 0;
    91 
     39    printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__ );
     40    CURRENT_THREAD->errno = ENOMEM;
     41    return -1;
    9242}  // end sys_readdir()
  • trunk/kernel/syscalls/sys_rmdir.c

    r305 r407  
    4040        process_t * process = this->process;
    4141
    42     // get pathname copy in kernel space
    43     error = hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    44 
    45     if( error )
     42    // check pathname length
     43    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
    4644    {
    4745        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
    48                 this->errno = ENFILE;
     46        this->errno = ENFILE;
    4947        return -1;
    5048    }
     49
     50    // copy pathname in kernel space
     51    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    5152
    5253    // get cluster and local pointer on reference process
  • trunk/kernel/syscalls/sys_signal.c

    r406 r407  
    4545        this->process->sig_mgr.sigactions[sig_id] = handler;
    4646
    47         signal_dmsg("\n[DMSG] %s : handler @%x has been registred for signal %d\n",
     47        signal_dmsg("\n[DBG] %s : handler @%x has been registred for signal %d\n",
    4848                    __FUNCTION__ , handler , sig_id );
    4949
  • trunk/kernel/syscalls/sys_stat.c

    r124 r407  
    3232#include <process.h>
    3333
    34 //////////////////////////////////////////
    35 int sys_stat( uint32_t            file_id,
    36               struct vfs_stat_s * stat )
     34/////////////////////////////////////
     35int sys_stat( char        * pathname,
     36              struct stat * u_stat )
    3737{
    38     error_t           error;
    39     paddr_t           paddr;
    40     struct vfs_stat_s k_stat;
    41     xptr_t            file_xp;
     38    error_t       error;
     39    paddr_t       paddr;
     40    struct stat   k_stat;       // kernel space
     41    xptr_t        file_xp;
     42    char          kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    4243       
    4344        thread_t  * this    = CURRENT_THREAD;
     
    4546
    4647    // check stat structure in user space
    47     error = vmm_v2p_translate( false , stat , &paddr );
     48    error = vmm_v2p_translate( false , u_stat , &paddr );
    4849
    4950        if( error )
     
    5556        }       
    5657
    57     // get extended pointer on remote file descriptor
    58     file_xp = process_fd_get_xptr( process , file_id );
    59 
    60     if( file_xp == XPTR_NULL )
     58    // check pathname length
     59    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
    6160    {
    62         printk("\n[ERROR] in %s : undefined file descriptor for thread %x in process %x\n",
    63                __FUNCTION__ , this->trdid , process->pid );
    64         this->errno = EBADFD;
     61        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     62        this->errno = ENFILE;
    6563        return -1;
    6664    }
    6765
    68     // call the relevant VFS function
     66    // copy pathname in kernel space
     67    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
     68
     69    // get cluster and local pointer on reference process
     70    xptr_t      ref_xp  = process->ref_xp;
     71    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     72    cxy_t       ref_cxy = GET_CXY( ref_xp );
     73
     74    // get extended pointer on cwd inode
     75    xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
     76
     77    // get the cwd lock in read mode from reference process
     78    remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     79
     80    // get extended pointer on remote file descriptor
     81    error = vfs_lookup( cwd_xp,
     82                        pathname,
     83                        0,
     84                        &file_xp );
     85
     86    // release the cwd lock
     87    remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     88
     89    if( error )
     90    {
     91        printk("\n[ERROR] in %s : cannot found file <%s> for thread %x in process %x\n",
     92               __FUNCTION__ , pathname , this->trdid , process->pid );
     93        this->errno = error;
     94        return -1;
     95    }
     96
     97    // call VFS function to get stat info
    6998    error = vfs_stat( file_xp,
    7099                      &k_stat );
    71100    if( error )
    72101        {
    73         printk("\n[ERROR] in %s : cannot access file %d for thread %x in process %x\n",
    74                __FUNCTION__ , file_id , this->trdid , process->pid );
     102        printk("\n[ERROR] in %s : cannot get stats for file %s\n",
     103               __FUNCTION__ , pathname );
    75104                this->errno = error;
    76105                return -1;
    77106        }
    78107   
    79     // copy stat to user space
    80     hal_copy_to_uspace( stat , &k_stat , sizeof(struct vfs_stat_s) );
     108    // copy k_stat to u_stat
     109    hal_copy_to_uspace( u_stat , &k_stat , sizeof(struct stat) );
    81110
    82111    hal_fence();
  • trunk/kernel/syscalls/sys_thread_create.c

    r406 r407  
    4040
    4141
    42 //////////////////////////////////////////////////////////////////////////////////////////
    43 // This function implements the pthread_create system call
    44 //////////////////////////////////////////////////////////////////////////////////////////
    45 int sys_thread_create ( thread_t       * new_thread,    // [out] argument
    46                         pthread_attr_t * user_attr,     // [in] argument
    47                         void           * start_func,    // [in] argument
    48                         void           * start_arg )    // [in] argument
     42///////////////////////////////////////////////////
     43int sys_thread_create ( pthread_t      * trdid_ptr,
     44                        pthread_attr_t * user_attr,
     45                        void           * start_func,
     46                        void           * start_arg )
    4947{
    50         pthread_attr_t   k_attr;           // copy of pthread attributes in kernel space
     48        pthread_attr_t   kern_attr;        // copy of pthread attributes in kernel space
    5149        thread_t       * parent;           // pointer on thread executing the pthread_create
    5250        xptr_t           parent_xp;        // extended pointer on created thread
     
    5654        process_t      * process;          // pointer on local process descriptor
    5755        paddr_t          paddr;            // unused, required by vmm_v2p_translate()
     56    cxy_t            target_cxy;       // target cluster identifier
    5857        error_t          error;
    5958
     
    6362        tm_start = hal_get_cycles();
    6463
    65         // get parent thead pointer, extended pointer, and process pointer
     64        // get parent thead pointer, extended pointer, and process
    6665        parent     = CURRENT_THREAD;
    6766        parent_xp  = XPTR( local_cxy , parent );
    6867        process    = parent->process;
    6968
    70         // check user_attr in user space
    71         error = vmm_v2p_translate( false , user_attr , &paddr );
     69        // check user_attr in user space & copy to kernel space
     70    if( user_attr != NULL )
     71    {
     72            error = vmm_v2p_translate( false , user_attr , &paddr );
    7273
    73         if( error )
    74         {
    75                 printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ );
    76                 parent->errno = EINVAL;
    77                 return -1;
    78         }
     74            if( error )
     75            {
     76                    printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ );
     77                    parent->errno = EINVAL;
     78                    return -1;
     79            }
     80       
     81            hal_copy_from_uspace( &kern_attr , user_attr , sizeof(pthread_attr_t) );
     82    }
    7983
    8084        // check start_func in user space
     
    98102        }
    99103
    100         // copy user_attr structure from user space to kernel space
    101         hal_copy_from_uspace( &k_attr , user_attr , sizeof(pthread_attr_t) );
    102 
    103         // check/set "cxy" attribute
    104         if( k_attr.attributes & PT_ATTR_CLUSTER_DEFINED )
     104        // check / define attributes an target_cxy
     105    if( user_attr != NULL )                      // user defined attributes
     106    {
     107            // check / get target_cxy
     108            if( kern_attr.attributes & PT_ATTR_CLUSTER_DEFINED )
     109            {
     110                    if( cluster_is_undefined( kern_attr.cxy ) )
     111                    {
     112                            printk("\n[ERROR] in %s : illegal target cluster = %x\n",
     113                            __FUNCTION__ , kern_attr.cxy );
     114                            parent->errno = EINVAL;
     115                            return -1;
     116            }
     117            target_cxy = kern_attr.cxy;
     118                }
     119        else
     120        {
     121            target_cxy = dqdt_get_cluster_for_process();
     122        }
     123        }
     124        else                                        // set default attributes
    105125        {
    106                 if( cluster_is_undefined( k_attr.cxy ) )
    107                 {
    108                         printk("\n[ERROR] in %s : illegal target cluster attribute = %x\n",
    109                                __FUNCTION__ , k_attr.cxy );
    110                         parent->errno = EINVAL;
    111                         return -1;
    112                 }
    113         }
    114         else
    115         {
    116                 k_attr.cxy = dqdt_get_cluster_for_process();
     126        kern_attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED;
     127        target_cxy           = dqdt_get_cluster_for_process();
    117128        }
    118129
    119130        // create the thread, using a RPC if required
    120         // this returns "error", "child", and "child_xp"
     131        // this returns "error", "child_ptr", and "child_xp"
    121132
    122         if( k_attr.cxy == local_cxy )                         // target cluster is local
     133        if( target_cxy == local_cxy )                         // target cluster is local
    123134        {
    124135                // create thread in local cluster
     
    126137                                            start_func,
    127138                                            start_arg,
    128                                             &k_attr,
     139                                            &kern_attr,
    129140                                            &child_ptr );
    130141
     
    133144        else                                                 // target cluster is remote
    134145        {
    135                 rpc_thread_user_create_client( k_attr.cxy,
     146                rpc_thread_user_create_client( target_cxy,
    136147                                               process->pid,
    137148                                               start_func,
    138149                                               start_arg,
    139                                                &k_attr,
     150                                               &kern_attr,
    140151                                               &child_xp,
    141152                                               &error );
     
    152163
    153164        // returns trdid to user space
    154         trdid = hal_remote_lw( XPTR( k_attr.cxy , &child_ptr->trdid ) );
    155         hal_copy_to_uspace( new_thread , &trdid , sizeof(pthread_t) );
     165        trdid = hal_remote_lw( XPTR( target_cxy , &child_ptr->trdid ) );
     166        hal_copy_to_uspace( trdid_ptr , &trdid , sizeof(pthread_t) );
    156167
    157         // register new-thread in parent-thread children list if required
    158         if( (k_attr.attributes & PT_ATTR_DETACH) == 0 )
    159             thread_child_parent_link( parent_xp , child_xp );
     168    // register child in parent if required
     169    if( user_attr != NULL )
     170    {
     171            if( (kern_attr.attributes & PT_ATTR_DETACH) == 0 )
     172                thread_child_parent_link( parent_xp , child_xp );
     173    }
     174
     175    // activate new thread
     176        thread_unblock( child_xp , THREAD_BLOCKED_GLOBAL );
     177
     178    hal_fence();
    160179
    161180        tm_end = hal_get_cycles();
    162181
    163         thread_dmsg("\n[DMSG] %s created thread %x for process %x in cluster %x\n"
    164                     "  start_cycle = %d / end_cycle = %d\n",
    165                        trdid , process->pid , k_attr.cxy , tm_start , tm_end );
     182syscall_dmsg("\n[DBG] %s : core[%x,%d] created thread %x for process %x / cycle %d\n"
     183"      cluster %x / cost = %d cycles\n",
     184__FUNCTION__ , local_cxy , parent->core->lid , trdid , process->pid , tm_end ,
     185target_cxy , tm_end - tm_start );
     186
    166187        return 0;
    167 }
    168188
     189}  // end sys_thread_create()
     190
  • trunk/kernel/syscalls/sys_thread_exit.c

    r296 r407  
    3838    reg_t       irq_state;
    3939
    40     // register the exit_value in thread descriptor
     40    // register the exit_value pointer in thread descriptor
    4141    this->exit_value = exit_value;
    4242
    43     // we enter the join loop to wait the join
    44     // only if thread is joinable
     43    // enter the join loop to wait the join if thread is joinable
    4544    if( (this->flags & THREAD_FLAG_DETACHED) == 0 )
    4645    {
     
    7473
    7574                // deschedule
    76                 sched_yield( NULL );
     75                sched_yield();
    7776            }     
    7877        }
  • trunk/kernel/syscalls/sys_thread_join.c

    r296 r407  
    138138
    139139            // deschedule
    140             sched_yield( NULL );
     140            sched_yield();
    141141        }
    142142    }
  • trunk/kernel/syscalls/sys_thread_sleep.c

    r406 r407  
    3232    thread_t * this = CURRENT_THREAD;
    3333
    34     thread_dmsg("\n[DMSG] %s : thread %x in process %x goes to sleep at cycle %d\n",
     34    thread_dmsg("\n[DBG] %s : thread %x in process %x goes to sleep at cycle %d\n",
    3535                __FUNCTION__, this->trdid, this->process->pid, hal_get_cycles() );
    3636
    3737    thread_block( this , THREAD_BLOCKED_GLOBAL );
    38     sched_yield( NULL );
     38    sched_yield();
    3939
    40     thread_dmsg("\n[DMSG] %s : thread %x in process %x resume at cycle\n",
     40    thread_dmsg("\n[DBG] %s : thread %x in process %x resume at cycle\n",
    4141                __FUNCTION__, this->trdid, this->process->pid, hal_get_cycles() );
    4242
  • trunk/kernel/syscalls/sys_thread_yield.c

    r296 r407  
    2727int sys_thread_yield()
    2828{
    29         sched_yield( NULL );
     29        sched_yield();
    3030        return 0;
    3131}
  • trunk/kernel/syscalls/sys_timeofday.c

    r124 r407  
    3030#include <vmm.h>
    3131#include <core.h>
    32 #include <time.h>
     32#include <shared_syscalls.h>
    3333
    3434////////////////////////////////////////
  • trunk/kernel/syscalls/sys_trace.c

    r406 r407  
    4949        // desactivate thread trace TODO
    5050
    51             printk("\n[DMSG] %s : trace OFF  for thread %x in process %x\n",
     51            printk("\n[DBG] %s : trace OFF  for thread %x in process %x\n",
    5252               __FUNCTION__ , trdid , pid );
    5353    }
     
    5656        // activate thread trace TODO
    5757                   
    58             printk("\n[DMSG] %s : trace ON for thread %x in process %x\n",
     58            printk("\n[DBG] %s : trace ON for thread %x in process %x\n",
    5959               __FUNCTION__ , trdid , pid );
    6060    }
  • trunk/kernel/syscalls/sys_unlink.c

    r305 r407  
    3737    process_t    * process  = this->process;
    3838
    39     // get pathname copy in kernel space
    40     error = hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    41 
    42     if( error )
     39    // check pathname length
     40    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
    4341    {
    4442        printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     
    4644        return -1;
    4745    }
     46
     47    // copy pathname in kernel space
     48    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    4849
    4950    // get cluster and local pointer on reference process
  • trunk/kernel/syscalls/sys_write.c

    r315 r407  
    3232#include <process.h>
    3333
    34 /* TODO: user page(s) need to be locked [AG] */
     34/* TODO: concurrent user page(s) unmap need to be handled [AG] */
    3535
    3636//////////////////////////////////
    3737int sys_write( uint32_t   file_id,
    38                void     * buf,
     38               void     * vaddr,
    3939               uint32_t   count )
    4040{
    4141    error_t      error;
    42     paddr_t      paddr;                // required for user space checking
     42    paddr_t      paddr;                // unused, but required for user space checking
    4343        xptr_t       file_xp;              // remote file extended pointer
     44    uint32_t     nbytes;               // number of bytes actually written
     45
     46        uint32_t     tm_start;
     47        uint32_t     tm_end;
     48
     49        tm_start = hal_get_cycles();
    4450
    4551        thread_t   * this = CURRENT_THREAD;
     
    5561
    5662    // check user buffer in user space
    57     error = vmm_v2p_translate( false , buf , &paddr );
     63    error = vmm_v2p_translate( false , vaddr , &paddr );
    5864
    5965    if ( error )
    6066    {
    6167        printk("\n[ERROR] in %s : user buffer unmapped = %x\n",
    62                __FUNCTION__ , (intptr_t)buf );
     68        __FUNCTION__ , (intptr_t)vaddr );
    6369                this->errno = EINVAL;
    6470                return -1;
     
    7076    if( file_xp == XPTR_NULL )
    7177    {
    72         printk("\n[ERROR] in %s : undefined file descriptor index = %d\n",
    73                __FUNCTION__ , file_id );
     78        printk("\n[ERROR] in %s : undefined file descriptor index = %d in process %x\n",
     79        __FUNCTION__ , file_id , process->pid );
    7480                this->errno = EBADFD;
    7581                return -1;
     
    8490    if( (attr & FD_ATTR_WRITE_ENABLE) == 0 )
    8591        {
    86         printk("\n[ERROR] in %s : file %d not writable\n",
    87                __FUNCTION__ , file_id );
     92        printk("\n[ERROR] in %s : file %d not writable in process %x\n",
     93        __FUNCTION__ , file_id , process->pid );
    8894                this->errno = EBADFD;
    8995                return -1;
    9096        }
    9197   
    92     // transfer count bytes directly from user buffer to mapper
    93     error = vfs_user_move( false,               // from buffer
    94                            file_xp,
    95                            buf ,
    96                            count );
     98    // get file type
     99    vfs_inode_type_t type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type ) );
    97100
    98     if( error )
     101    // action depend on file type
     102    if( type == INODE_TYPE_FILE )      // transfer count bytes to file mapper
    99103    {
    100         printk("\n[ERROR] in %s cannot read data from file %d\n",
    101                __FUNCTION__ , file_id );
     104        nbytes = vfs_user_move( false,               // from buffer to mapper
     105                                file_xp,
     106                                vaddr,
     107                                count );
     108    }
     109    else if( type == INODE_TYPE_DEV )  // transfer count bytes to device
     110    {
     111        nbytes = devfs_user_move( false,             // from buffer to device
     112                                 file_xp,
     113                                 vaddr,
     114                                 count );
     115    }
     116    else
     117    {
     118        nbytes = 0;
     119        panic("file type %d non supported", type );
     120    }
     121
     122    if( nbytes != count )
     123    {
     124        printk("\n[ERROR] in %s cannot write data to file %d in process %x\n",
     125        __FUNCTION__ , file_id , process->pid );
    102126        this->errno = error;
    103127        return -1;
     
    106130    hal_fence();
    107131
    108         return 0;
     132    tm_end = hal_get_cycles();
     133
     134syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / nbytes = %d / cycle %d\n"
     135" first byte = %c / file_id = %d / cost = %d\n",
     136__FUNCTION__ , local_cxy , this->core->lid , this->trdid , nbytes , tm_start ,
     137*((char *)(intptr_t)paddr) , file_id , tm_end - tm_start );
     138 
     139        return nbytes;
    109140
    110141}  // end sys_write()
  • trunk/kernel/syscalls/syscalls.h

    r279 r407  
    11/*
    2  * syscalls.h - kernel services definition
     2 * syscalls.h - Kernel side services for syscall handling.
    33 *
    44 * Author     Alain Greiner (2016,2017)
     
    2626
    2727#include <hal_types.h>
    28 #include <time.h>
    29 
    30 /*****   Forward declarations  *****/
     28#include <shared_syscalls.h>
     29
     30/**   Forward declarations  *****/
    3131
    3232struct thread_s;                  // defined in thread.h
     
    3636struct mmap_attr_s;               // defined in vmm.h
    3737
    38 /******************************************************************************************
    39  * This enum defines the mnemonics for the syscall indexes.
    40  * It must be kept consistent with the array defined in do_syscalls.c
    41  *****************************************************************************************/
    42 enum
    43 {
    44         SYS_THREAD_EXIT    = 0,
    45         SYS_MMAP           = 1,
    46         SYS_THREAD_CREATE  = 2,
    47         SYS_THREAD_JOIN    = 3,
    48         SYS_THREAD_DETACH  = 4,
    49         SYS_THREAD_YIELD   = 5,
    50         SYS_SEM            = 6,
    51         SYS_CONDVAR        = 7,
    52         SYS_BARRIER        = 8,
    53         SYS_MUTEX          = 9,
    54 
    55         SYS_SLEEP          = 10,
    56         SYS_WAKEUP         = 11,
    57         SYS_OPEN           = 12,
    58         SYS_CREAT          = 13,
    59         SYS_READ           = 14,
    60         SYS_WRITE          = 15,
    61         SYS_LSEEK          = 16,
    62         SYS_CLOSE          = 17,
    63         SYS_UNLINK         = 18,   
    64         SYS_PIPE           = 19,
    65 
    66         SYS_CHDIR          = 20,
    67         SYS_MKDIR          = 21,
    68         SYS_MKFIFO         = 22,   
    69         SYS_OPENDIR        = 23,
    70         SYS_READDIR        = 24,
    71         SYS_CLOSEDIR       = 25,
    72         SYS_GETCWD         = 26,
    73         SYS_CLOCK          = 27,
    74         SYS_ALARM          = 28,   
    75         SYS_RMDIR          = 29,
    76 
    77         SYS_UTLS           = 30, 
    78         SYS_CHMOD          = 31,
    79         SYS_SIGNAL         = 32,
    80         SYS_TIMEOFDAY      = 33,
    81         SYS_KILL           = 34,
    82         SYS_GETPID         = 35,
    83         SYS_FORK           = 36,
    84         SYS_EXEC           = 37,
    85         SYS_STAT           = 38,     
    86         SYS_TRACE          = 39,
    87        
    88         SYSCALLS_NR        = 40,
    89 };
    90 
    91 
    92 /********************************************************************************************/
    93 /********************    system calls    ****************************************************/
    94 /********************************************************************************************/
    95 
    96 /*********************************************************************************************
    97  * [0] This function terminates the execution of the calling user thread value,
     38/******************************************************************************************
     39 * [0] This function terminates the execution of the calling user thread,
    9840 * and makes the exit_value pointer available to any successful pthread_join() with the
    9941 * terminating thread.
    100  *********************************************************************************************
    101  * @ exit_vallue  : [out] pointer to to the parrent thread if attached.
    102  * @ return 0 if success / return -1 if failure.
    103  ********************************************************************************************/
     42 ******************************************************************************************
     43 * @ exit_vallue  : pointer to be returned to parent thread if thead is attached.
     44 * @ return 0 if success / return -1 if failure.
     45 *****************************************************************************************/
    10446int sys_thread_exit( void * exit_value );
    10547
    106 /*********************************************************************************************
    107  * [1] This function map physical memory (or a file) in the calling thread virtual space.
    108  * The <attr> argument is a pointer on a structure containing arguments, defined in vmm.h.
    109  * TODO not implemented yet...
    110  *********************************************************************************************
    111  * @ attr       : pointer on attributes structure.
    112  * @ return 0 if success / return -1 if failure.
    113  ********************************************************************************************/
    114 int sys_mmap( struct mmap_attr_s * attr );
    115 
    116 /*********************************************************************************************
     48/******************************************************************************************
     49 * [1] This function calls the scheduler for the core running the calling thread.
     50 ******************************************************************************************
     51 * @ x_size   : [out] number of clusters in a row.
     52 * @ y_size   : [out] number of clusters in a column.
     53 * @ ncores   : [out] number of cores per cluster.
     54 * @ return always 0.
     55 *****************************************************************************************/
     56int sys_thread_yield();
     57
     58/******************************************************************************************
    11759 * [2] This function creates a new user thread. The <user_attr> argument is a pointer
    11860 * on astructure containing the thread attributes, defined in thread.h file.
    119  *********************************************************************************************
     61 ******************************************************************************************
    12062 * @ new_thread  : [out] local pointer on created thread descriptor.
    12163 * @ user_attr   : [in]  pointer on thread attributes structure.
     
    12365 * @ start_args  : [in]  pointer on start function arguments.
    12466 * @ return 0 if success / return -1 if failure.
    125  ********************************************************************************************/
     67 *****************************************************************************************/
    12668int sys_thread_create( struct thread_s        * new_thread,
    12769                       struct pthread_attr_s  * user_attr,
     
    12971                       void                   * start_args );
    13072
    131 /*********************************************************************************************
     73/******************************************************************************************
    13274 * [3] This blocking function suspend execution of the calling thread until completion
    13375 * of another target thread identified by the <trdid> argument.
    13476 * If the <exit_value> argument is not NULL, the value passed to pthread_exit() by the
    13577 * target thread is stored in the location referenced by exit_value.
    136  *********************************************************************************************
     78 ******************************************************************************************
    13779 * @ trdid     : [in]  target thread identifier.
    13880 * @ thread    : [out] buffer for exit_value returned by target thread.
    13981 * @ return 0 if success / return -1 if failure.
    140  ********************************************************************************************/
     82 *****************************************************************************************/
    14183int sys_thread_join( trdid_t    trdid,
    14284                     void    ** exit_value );
    14385
    144 /*********************************************************************************************
     86/******************************************************************************************
    14587 * [4] This function detach a joinable thread.
    146  *********************************************************************************************
    147  * @ trdid   : thread identifier.
    148  * @ return 0 if success / return -1 if failure.
    149  ********************************************************************************************/
     88 ******************************************************************************************
     89 * @ trdid   : thread identifier.i
     90 * @ return 0 if success / return -1 if failure.
     91 *****************************************************************************************/
    15092int sys_thread_detach( trdid_t  trdid );
    15193
    152 /*********************************************************************************************
    153  * [5] This function calls the scheduler for the core running the calling thread.
    154  *********************************************************************************************
    155  * @ return always 0.
    156  ********************************************************************************************/
    157 int sys_thread_yield();
    158 
    159 /*********************************************************************************************
     94/******************************************************************************************
     95 * [5] This slot is not used.
     96 *****************************************************************************************/
     97
     98/******************************************************************************************
    16099 * [6] This function implement all operations on a POSIX unnamed semaphore,
    161100 * that can be shared by threads running in different clusters.
    162101 * The kernel structure representing a remote semaphore is in the remote_sem.h file,
    163102 * and the code implementing the operations is in the remore_sem.c file.
    164  *********************************************************************************************
     103 ******************************************************************************************
    165104 * @ vaddr     : semaphore virtual address in user space == identifier.
    166105 * @ operation : SEM_INIT / SEM_DESTROY / SEM_GETVALUE / SEM_POST / SEM_WAIT.
    167106 * @ value     : pointer on in/out argument in user space.
    168107 * @ return 0 if success / return -1 if failure.
    169  ********************************************************************************************/
     108 *****************************************************************************************/
    170109int sys_sem( void       * vaddr,
    171110             uint32_t     operation,
    172111             uint32_t   * value );
    173112
    174 typedef enum
    175 {
    176         SEM_INIT,
    177         SEM_DESTROY,
    178         SEM_GETVALUE,
    179         SEM_WAIT,
    180         SEM_POST,
    181 }
    182 sem_operation_t;
    183 
    184 /*********************************************************************************************
     113/******************************************************************************************
    185114 * [7] This function implement all operations on a POSIX condition variable.
    186115 * The kernel structure representing a cond_var is defined in the remote_cv.h file,
    187116 * The code implementing the operations is defined in the remote_cv.c file.
    188  *********************************************************************************************
     117 ******************************************************************************************
    189118 * @ vaddr     : condvar virtual address in user space == identifier.
    190119 * @ operation : operation type (see below).
    191120 * @ attr      : mutex virtual address in user space == identifier.
    192121 * @ return 0 if success / return -1 if failure.
    193  ********************************************************************************************/
     122 *****************************************************************************************/
    194123int sys_condvar( void     * condvar,
    195124                 uint32_t   operation,
    196125                 void     * mutex );
    197126
    198 typedef enum
    199 {
    200         CONDVAR_INIT,
    201         CONDVAR_DESTROY,
    202     CONDVAR_WAIT,
    203     CONDVAR_SIGNAL,
    204     CONDVAR_BROADCAST,
    205 }
    206 condvar_operation_t;
    207 
    208 /*********************************************************************************************
     127/******************************************************************************************
    209128 * [8] This function implement all operations on a POSIX barrier.
    210129 * The kernel structure representing a barrier is defined in the remote_barrier.h file.
    211130 * The code implementting the operations is defined in the remote_barrier.c file.
    212  *********************************************************************************************
     131 ******************************************************************************************
    213132 * @ vaddr     : barrier virtual address in user space == identifier.
    214133 * @ operation : BARRIER_INIT / BARRIER_DESTROY / BARRIER_WAIT.
    215134 * @ count     : number of expected threads (only used by BARRIER_INIT operation).
    216135 * @ return 0 if success / return -1 if failure.
    217  ********************************************************************************************/
     136 *****************************************************************************************/
    218137int sys_barrier( void     * vaddr,
    219138                 uint32_t   operation,
    220139                 uint32_t   count );
    221140
    222 typedef enum
    223 {
    224         BARRIER_INIT,
    225         BARRIER_DESTROY,
    226         BARRIER_WAIT,
    227 }
    228 barrier_operation_t;
    229 
    230 /*********************************************************************************************
     141/******************************************************************************************
    231142 * [9] This function implement all operations on a POSIX mutex.
    232143 * The kernel structure representing a barrier is defined in the remote_barrier.h file.
    233144 * The code implementting the operations is defined in the remote_barrier.c file.
    234  *********************************************************************************************
     145 ******************************************************************************************
    235146 * @ vaddr     : mutex virtual address in user space == identifier.
    236147 * @ operation : MUTEX_INIT / MUTEX_DESTROY / MUTEX_LOCK / MUTEX_UNLOCK
    237148 * @ attr      : mutex attributes (non supported yet => must be 0).
    238149 * @ return 0 if success / return -1 if failure.
    239  ********************************************************************************************/
     150 *****************************************************************************************/
    240151int sys_mutex( void     * vaddr,
    241152               uint32_t   operation,
    242153               uint32_t   count );
    243154
    244 typedef enum
    245 {
    246         MUTEX_INIT,
    247         MUTEX_DESTROY,
    248         MUTEX_LOCK,
    249         MUTEX_UNLOCK,
    250 }
    251 mutex_operation_t;
    252 
    253 /*********************************************************************************************
    254  * [10] This function block the calling thread on the THREAD_BLOCKED_GLOBAL condition,
    255  * and deschedule.
    256  *********************************************************************************************
    257  * @ return 0 if success / returns -1 if failure.
    258  ********************************************************************************************/
    259 int sys_thread_sleep();
    260 
    261 /*********************************************************************************************
    262  * [11] This function unblock the thread identified by its <trdid> from the
    263  * THREAD_BLOCKED_GLOBAL condition.
    264  *********************************************************************************************
    265  * @ trdid  : target thread identifier.
    266  * @ return 0 if success / return -1 if failure.
    267  ********************************************************************************************/
    268 int sys_thread_wakeup();
    269 
    270 /*********************************************************************************************
    271  * [12] This function open or create a file.
    272  *********************************************************************************************
     155/******************************************************************************************
     156 * [10] This slot not allocated yet
     157 ******************************************************************************************
     158 * @ return 0 if success / returns -1 if failure.
     159 *****************************************************************************************/
     160
     161/******************************************************************************************
     162 * [11] This function rmove an existing mapping defined by the <addr> and <size>
     163 * arguments in user space.
     164 ******************************************************************************************
     165 * @ addr  : base address in user space.
     166 * # size  : number of bytes.
     167 * @ return 0 if success / return -1 if failure.
     168 *****************************************************************************************/
     169int sys_munmap( void     * addr,
     170                uint32_t   size );
     171
     172/******************************************************************************************
     173 * [12] This function open or create an open file descriptor.
     174 ******************************************************************************************
    273175 * @ pathname   : pathname (can be relative or absolute).
    274176 * @ flags      : bit vector attributes (see below).
    275177 * @ mode       : access rights.
    276178 * @ return file descriptor index in fd_array if success / return -1 if failure.
    277  ********************************************************************************************/
     179 *****************************************************************************************/
    278180int sys_open( char    * pathname,
    279181              uint32_t  flags,
    280182              uint32_t  mode );
    281183
    282 typedef enum
    283 {
    284     O_RDONLY   = 0x0010000,    /*! open file in read-only mode                              */
    285     O_WRONLY   = 0x0020000,    /*! open file in write-only mode                             */
    286     O_RDWR     = 0x0030000,    /*! open file in read/write mode                             */
    287     O_NONBLOCK = 0x0040000,    /*! do not block if data non available                       */
    288     O_APPEND   = 0x0080000,    /*! append on each write                                     */
    289     O_CREAT    = 0x0100000,    /*! create file if it does not exist                         */
    290     O_TRUNC    = 0x0200000,    /*! file length is forced to 0                               */
    291     O_EXCL     = 0x0400000,    /*! error if VFS_O_CREAT and file exist                      */
    292     O_SYNC         = 0x0800000,    /*! synchronize File System on each write                    */
    293     O_CLOEXEC  = 0x1000000,    /*! set the close-on-exec flag in file descriptor            */
    294     O_DIR      = 0x2000000,    /*! new file descriptor is for a directory                   */
    295 }
    296 open_attributes_t;
    297 
    298 /*********************************************************************************************
    299  * [13] This function creates a new file as specified by the arguments.
    300  * This function is obsolete, you should use open() with 0_CREATE.
    301  *********************************************************************************************
    302  * @ pathname   : pathname (can be relative or absolute).
    303  * @ mode       : access rights.
    304  ********************************************************************************************/
    305 int sys_creat( char     * pathname,
    306                uint32_t   mode );
    307 
    308 /*********************************************************************************************
     184/******************************************************************************************
     185 * [13] This function map physical memory (or a file) in the calling thread virtual space.
     186 * The <attr> argument is a pointer on a structure for arguments (see shared_syscalls.h).
     187 ******************************************************************************************
     188 * @ attr       : pointer on attributes structure.
     189 * @ return 0 if success / return -1 if failure.
     190 *****************************************************************************************/
     191int sys_mmap( mmap_attr_t * attr );
     192
     193/******************************************************************************************
    309194 * [14] This function read bytes from an open file identified by its file descriptor.
    310  * This file can be a regular file or character oriented device.
    311  *********************************************************************************************
     195 * The file can be a regular file or character oriented device.
     196 ******************************************************************************************
    312197 * @ file_id  : open file index in fd_array.
    313198 * @ buf      : buffer virtual address in user space.
    314199 * @ count    : number of bytes.
    315200 * @ return number of bytes actually read if success / returns -1 if failure.
    316  ********************************************************************************************/
     201 *****************************************************************************************/
    317202int sys_read( uint32_t   file_id,
    318203              void     * buf,
    319204              uint32_t   count );
    320205
    321 /*********************************************************************************************
     206/******************************************************************************************
    322207 * [15] This function writes bytes to an open file identified by its file descriptor.
    323  * This file can be a regular file or character oriented device.
    324  *********************************************************************************************
     208 * The file can be a regular file or character oriented device.
     209 ******************************************************************************************
    325210 * @ file_id  : open file index in fd_array.
    326211 * @ buf      : buffer virtual address in user space.
    327212 * @ count    : number of bytes.
    328213 * @ return number of bytes actually written if success / returns -1 if failure.
    329  ********************************************************************************************/
     214 *****************************************************************************************/
    330215int sys_write( uint32_t   file_id,
    331216               void     * buf,
    332217               uint32_t   count );
    333218
    334 /*********************************************************************************************
    335  * [16] This function epositions the offset of the file descriptor identified by <file_id>,
    336  * according to the operation type defined by the <whence> and <offset> arguments.
    337  *********************************************************************************************
     219/******************************************************************************************
     220 * [16] This function repositions the offset of the file descriptor identified by <file_id>,
     221 * according to the operation type defined by the <whence> argument.
     222 ******************************************************************************************
    338223 * @ file_id  : open file index in fd_array.
    339  * @ offset   : buffer virtual address in user space.
     224 * @ offset   : used to compute new offset value.
    340225 * @ whence   : operation type (see below).
    341226 * @ return 0 if success / returns -1 if failure.
    342  ********************************************************************************************/
     227 *****************************************************************************************/
    343228int sys_lseek( xptr_t    file_id,
    344229               uint32_t  offset,
    345230               uint32_t  whence );
    346231
    347 typedef enum
    348 {
    349     SEEK_SET  = 0,     /*! new_offset <= offset                                             */
    350     SEEK_CUR  = 1,     /*! new_offset <= current_offset + offset                            */
    351     SEEK_END  = 2,     /*! new_iffset <= current_size + offset                              */
    352 }
    353 lseek_operation_t;
    354 
    355 /*********************************************************************************************
     232/******************************************************************************************
    356233 * [17] This function release the memory allocated for the file descriptor identified by
    357234 * the <file_id> argument, and remove the fd array_entry in all copies of the process
    358235 * descriptor.
    359  *********************************************************************************************
     236 ******************************************************************************************
    360237  file_id   : file descriptor index in fd_array.
    361238 * @ return 0 if success / returns -1 if failure.
    362  ********************************************************************************************/
     239 *****************************************************************************************/
    363240int sys_close( uint32_t file_id );
    364241
    365 /*********************************************************************************************
    366  * [18] This function removes a directory entry identified by the <pathname> from its
     242/******************************************************************************************
     243 * [18] This function removes a directory entry identified by the <pathname> from the
    367244 * directory, and decrement the link count of the file referenced by the link.
    368245 * If the link count reduces to zero, and no process has the file open, then all resources
     
    370247 * the last link is removed, the link is removed, but the removal of the file is delayed
    371248 * until all references to it have been closed.
    372  *********************************************************************************************
    373  * @ pathname   : pathname (can be relative or absolute).
    374  * @ return 0 if success / returns -1 if failure.
    375  ********************************************************************************************/
     249 ******************************************************************************************
     250 * @ pathname   : pathname (can be relative or absolute).
     251 * @ return 0 if success / returns -1 if failure.
     252 *****************************************************************************************/
    376253int sys_unlink( char * pathname );
    377254
    378 /*********************************************************************************************
     255/******************************************************************************************
    379256 * [19] This function creates in the calling thread cluster an unnamed pipe, and two
    380257 * (read and write) file descriptors.
    381  *********************************************************************************************
     258 * TODO not implemented yet...
     259 ******************************************************************************************
    382260 * @ file_id[0] : [out] read only file descriptor index.
    383261 * @ file_id[1] : [out] write only file descriptor index.
    384262 * @ return 0 if success / return -1 if failure.
    385  ********************************************************************************************/
     263 *****************************************************************************************/
    386264int sys_pipe( uint32_t file_id[2] );
    387265
    388 /*********************************************************************************************
     266/******************************************************************************************
    389267 * [20] This function change the current working directory in reference process descriptor.
    390  *********************************************************************************************
    391  * @ pathname   : pathname (can be relative or absolute).
    392  * @ return 0 if success / returns -1 if failure.
    393  ********************************************************************************************/
     268 ******************************************************************************************
     269 * @ pathname   : pathname (can be relative or absolute).
     270 * @ return 0 if success / returns -1 if failure.
     271 *****************************************************************************************/
    394272int sys_chdir( char * pathname );
    395273
    396 /*********************************************************************************************
     274/******************************************************************************************
    397275 * [21] This function creates a new directory in file system.
    398  *********************************************************************************************
     276 ******************************************************************************************
    399277 * @ pathname   : pathname (can be relative or absolute).
    400278 * @ mode       : access rights (as defined in chmod).
    401279 * @ return 0 if success / returns -1 if failure.
    402  ********************************************************************************************/
     280 *****************************************************************************************/
    403281int sys_mkdir( char    * pathname,
    404282               uint32_t  mode );
    405283
    406 /*********************************************************************************************
     284/******************************************************************************************
    407285 * [22] This function creates a named FIFO file in the calling thread cluster.
    408286 * The associated read and write file descriptors mut be be  explicitely created
    409  * using the sy_open() function.
    410  *********************************************************************************************
     287 * using the sys_open() function.
     288 ******************************************************************************************
    411289 * @ pathname   : pathname (can be relative or absolute).
    412290 * @ mode       : access rights (as defined in chmod).
    413291 * @ return 0 if success / returns -1 if failure.
    414  ********************************************************************************************/
     292 *****************************************************************************************/
    415293int sys_mkfifo( char     * pathname,
    416294                uint32_t   mode );
    417295
    418 /*********************************************************************************************
    419  * [23] This function open a directory, that must exist in the file system.
    420  *********************************************************************************************
    421  * @ pathname   : pathname (can be relative or absolute).
    422  * @ return file descriptor index in fd_array if success / return -1 if failure.
    423  ********************************************************************************************/
    424 int sys_opendir( char * pathname );
    425 
    426 /*********************************************************************************************
    427  * [24] This function returns in the structure pointed by the <dirent> argument various
    428  * information about an entry of the directory identified by the <file_id> argument.
    429  *********************************************************************************************
    430  * @ file_id   : file descriptor index of the searched directory.
    431  * @ dirent    : pointer on a dirent structure in user space.
    432  * @ return 0 if success / returns -1 if failure.
    433  ********************************************************************************************/
    434 int sys_readdir( uint32_t              file_id,
    435                  struct vfs_dirent_s * dirent );
    436 
    437 /*********************************************************************************************
    438  * [25] This function close the file descriptor previouly open by the opendir() function.
    439  *********************************************************************************************
    440  * @ file_id   : file descriptor index of the searched directory.
    441  * @ return 0 if success / returns -1 if failure.
    442  ********************************************************************************************/
    443 int sys_closedir( uint32_t file_id );
    444 
    445 /*********************************************************************************************
     296/******************************************************************************************
     297 * [23] This function open a directory, that must exist in the file system, returning
     298 * a DIR pointer on the directory in user space.
     299 ******************************************************************************************
     300 * @ pathname   : pathname (can be relative or absolute).
     301 * @ dirp       : [out] buffer for pointer on user directory (DIR).
     302 * @ return 0 if success / returns -1 if failure.
     303 *****************************************************************************************/
     304int sys_opendir( char * pathname,
     305                 DIR ** dirp );
     306
     307/******************************************************************************************
     308 * [24] This function returns an user pointer on the dirent structure describing the
     309 * next directory entry in the directory identified by the <dirp> argument.
     310 ******************************************************************************************
     311 * @ dirp     : user pointer identifying the searched directory.
     312 * @ dentp    : [out] buffer for pointer on user direntory entry (dirent).
     313 * @ return O if success / returns -1 if failure.
     314 *****************************************************************************************/
     315int sys_readdir( DIR            * dirp,
     316                 struct dirent ** dentp );
     317
     318/******************************************************************************************
     319 * [25] This function closes the directory identified by the <dirp> argument, and releases
     320 * all structures associated with the <dirp> pointer.
     321 ******************************************************************************************
     322 * @ dirp     : user pointer identifying the directory.
     323 * @ return 0 if success / returns -1 if failure.
     324 *****************************************************************************************/
     325int sys_closedir( DIR * dirp );
     326
     327/******************************************************************************************
    446328 * [26] This function returns the pathname of the current working directory.
    447  *********************************************************************************************
     329 ******************************************************************************************
    448330 * buf     : buffer addres in user space.
    449331 * nbytes  : user buffer size in bytes.
    450332 * @ return 0 if success / returns -1 if failure.
    451  ********************************************************************************************/
     333 *****************************************************************************************/
    452334int sys_getcwd( char     * buf,
    453335                uint32_t   nbytes );
    454336
    455 /*********************************************************************************************
    456  * [27] This function returns in a 64 bits user buffer the calling core cycles count.
    457  * It uses both the hardware register and the core descriptor cycles count tos take
    458  * into account a possible harware register overflow  in 32 bits architectures.
    459  *********************************************************************************************
    460  * cyles    : [out] address of buffer in user space.
    461  ********************************************************************************************/
    462 int sys_clock( uint64_t * cycles );
    463 
    464 /*********************************************************************************************
     337/******************************************************************************************
     338 * [27] This slot is not used.
     339 *****************************************************************************************/
     340
     341/******************************************************************************************
    465342 * [28] This function forces the calling thread to sleep, for a fixed number of cycles.
    466  *********************************************************************************************
     343 ******************************************************************************************
    467344 * cycles   : number of cycles.
    468  ********************************************************************************************/
     345 *****************************************************************************************/
    469346int sys_alarm( uint32_t cycles );
    470347
    471 /*********************************************************************************************
    472  * [29] This undefined function does nothing.
    473  *********************************************************************************************
    474  * @ pathname   : pathname (can be relative or absolute).
    475  * @ return 0 if success / returns -1 if failure.
    476  ********************************************************************************************/
     348/******************************************************************************************
     349 * [29] This function removes a directory file whose name is given by <pathname>.
     350 * The directory must not have any entries other than `.' and `..'.
     351 ******************************************************************************************
     352 * @ pathname   : pathname (can be relative or absolute).
     353 * @ return 0 if success / returns -1 if failure.
     354 *****************************************************************************************/
    477355int sys_rmdir( char * pathname );
    478356
    479 /*********************************************************************************************
     357/******************************************************************************************
    480358 * [30] This function implement the operations related to User Thread Local Storage.
    481359 * It is actually implemented as an uint32_t variable in the thread descriptor.
    482  *********************************************************************************************
     360 ******************************************************************************************
    483361 * @ operation  : UTLS operation type as defined below.
    484362 * @ value      : argument value for the UTLS_SET operation.
    485363 * @ return value for the UTLS_GET and UTLS_GET_ERRNO / return -1 if failure.
    486  ********************************************************************************************/
     364 *****************************************************************************************/
    487365int sys_utls( uint32_t operation,
    488366              uint32_t value );
    489367
    490 typedef enum
    491 {
    492     UTLS_SET       = 1,
    493     UTLS_GET       = 2,
    494     UTLS_GET_ERRNO = 3,
    495 }
    496 utls_operation_t;
    497 
    498 /*********************************************************************************************
     368/******************************************************************************************
    499369 * [31] This function change the acces rights for the file/dir identified by the
    500370 * pathname argument.
    501  *********************************************************************************************
     371 ******************************************************************************************
    502372 * @ pathname   : pathname (can be relative or absolute).
    503373 * @ rights     : acces rights.
    504374 * @ return 0 if success / returns -1 if failure.
    505  ********************************************************************************************/
     375 *****************************************************************************************/
    506376int sys_chmod( char     * pathname,
    507377               uint32_t   rights );
    508378
    509 /*********************************************************************************************
     379/******************************************************************************************
    510380 * [32] This function associate a specific signal handler to a given signal type.
    511381 * Tee handlers for the SIGKILL and SIGSTOP signals cannot be redefined.
    512  *********************************************************************************************
     382 ******************************************************************************************
    513383 * @ sig_id    : index defining signal type (from 1 to 31).
    514384 * @ handler   : pointer on fonction implementing the specific handler.
    515385 * @ return 0 if success / returns -1 if failure.
    516  ********************************************************************************************/
     386 *****************************************************************************************/
    517387int sys_signal( uint32_t   sig_id,
    518388                void     * handler );
    519389
    520 /*********************************************************************************************
     390/******************************************************************************************
    521391 * [33] This function returns in the structure <tv>, defined in the time.h file,
    522392 * the current time (in seconds & micro-seconds).
    523393 * It is computed from the calling core descriptor.
    524394 * The timezone is not supported.
    525  *********************************************************************************************
     395 ******************************************************************************************
    526396 * @ tv      : pointer on the timeval structure.
    527397 * @ tz      : pointer on the timezone structure : must be NULL.       
    528398 * @ return 0 if success / returns -1 if failure.
    529  ********************************************************************************************/
     399 *****************************************************************************************/
    530400int sys_timeofday( struct timeval  * tv,
    531401                   struct timezone * tz );
    532402
    533 /*********************************************************************************************
     403/******************************************************************************************
    534404 * [34] This function implements the "kill" system call.
    535405 * It register the signal defined by the <sig_id> argument in all thread descriptors
     
    537407 * containing threads for the target process.
    538408 * It can be executed by any thread running in any cluster, as this function uses
    539  * remote access to traverse the list of process copies in the owner cluster,
     409 * remote access to traverse the list of process copies stored in the owner cluster,
    540410 * and the RPC_SIGNAL_RISE to signal the remote threads.
    541  *********************************************************************************************
     411 ******************************************************************************************
    542412 * @ pid      : target process identifier.
    543413 * @ sig_id   : index defining the signal type (from 1 to 31).
    544414 * @ return 0 if success / returns -1 if failure.
    545  ********************************************************************************************/
     415 *****************************************************************************************/
    546416int sys_kill( pid_t    pid,
    547417              uint32_t sig_id );
    548418
    549 /*********************************************************************************************
     419/******************************************************************************************
    550420 * [35] This function implements the "getpid" system call.
    551  *********************************************************************************************
    552  * @ returns the PID for the calling thread.
    553  ********************************************************************************************/
     421 ******************************************************************************************
     422 * @ returns the process PID for the calling thread.
     423 *****************************************************************************************/
    554424int sys_getpid();
    555425
    556 /*********************************************************************************************
     426/******************************************************************************************
    557427 * [36] This function implement the "fork" system call.
    558428 * The calling process descriptor (parent process), and the associated thread descriptor are
     
    560430 * is registered in another target cluster, that is the new process owner.
    561431 * The child process and the associated main thread will be migrated to the target cluster
    562  * later, when the child process makes an "exec" or any other system call. 
     432 * later, when the child process makes an "exec" or any other system call... TODO [AG]
    563433 * The target cluster depends on the "fork_user" flag and "fork_cxy" variable that can be
    564434 * stored in the calling thread descriptor by the specific fork_place() system call.
    565435 * If not, the sys_fork() function makes a query to the DQDT to select the target cluster.
    566  *********************************************************************************************
    567  * @ returns child process PID if success / returns -1 if failure
    568  ********************************************************************************************/
     436 ******************************************************************************************
     437 * @ if success, returns child process PID to parent, and return O to child.
     438 * @ if failure, returns -1 to parent / no child process is created.
     439 *****************************************************************************************/
    569440int sys_fork();
    570441
    571 /*********************************************************************************************
    572  * [37] This function implement the "exec" system call.
    573  * It is executed in the client cluster, but the new process descriptor and main thread
    574  * must be created in a server cluster, that is generally another cluster.
    575  * - if the server_cluster is the client cluster, call directly the process_make_exec()
     442/******************************************************************************************
     443 * [37] This function implement the "exec" system call, that creates a new process
     444 * descriptor.
     445 * It is executed in the client cluster, but the new process descriptor and the main
     446 * thread are created in a server cluster, that is generally another cluster.
     447 * - if the server_cluster is the client cluster, it calls directly the process_make_exec()
    576448 *   function to create a new process, and launch a new thread in local cluster.
    577  * - if the target_cluster is remote, call rpc_process_exec_client() to execute the
    578  *   process_make_exec() on the remote cluster.
     449 * - if the target_cluster is remote, it calls the rpc_process_exec_client() to execute
     450 *   process_signedmake_exec() on the remote cluster.
    579451 * In both case this function build an exec_info_t structure containing all informations
    580452 * required to build the new process descriptor and the associated thread.
    581453 * Finally, the calling process and thread are deleted.
    582  *********************************************************************************************
    583  * @ filename : string pointer on .elf filename (virtual pointer in user space)
    584  * @ argv     : array of strings on process arguments (virtual pointers in user space)
    585  * @ envp     : array of strings on Renvironment variables (virtual pointers in user space)
     454 ******************************************************************************************
     455 * @ filename : string pointer on .elf filename (pointer in user space)
     456 * @ argv     : array of strings on process arguments (pointers in user space)
     457 * @ envp     : array of strings on environment variables (pointers in user space)
    586458 * @ returns O if success / returns -1 if failure.
    587  ********************************************************************************************/
     459 *****************************************************************************************/
    588460int sys_exec( char  * filename,
    589461              char ** argv,
    590462              char ** envp );
    591463
    592 /*********************************************************************************************
    593  * [38] This function  returns in the <stat> structure, defined in the vfs.h file,
    594  * various informations on the file/directory identified by the <file_id> argument.
    595  *********************************************************************************************
    596  * @ file_id   : file descriptor index in fd_array.
    597  * @ stat      : pointer on the stat structure.
     464/******************************************************************************************
     465 * [38] This function  returns in the <stat> structure, defined in the "shared_syscalls.h"
     466 * file, various informations on the file/directory identified by the <pathname> argument.
     467 ******************************************************************************************
     468 * @ pathname  : user pointer on file pathname.
     469 * @ stat      : user pointer on the stat structure.
    598470 * @ returns O if success / returns -1 if failure.
    599  ********************************************************************************************/
    600 int sys_stat( uint32_t            file_id,
    601               struct vfs_stat_s * stat );
    602 
    603 /*********************************************************************************************
    604  * [39] This function is used to activate / desactivate Rthe trace for a thread
     471 *****************************************************************************************/
     472int sys_stat( const char  * pathname,
     473              struct stat * stat );
     474
     475/******************************************************************************************
     476 * [39] This non-standard function is used to activate / desactivate the trace for a thread
    605477 * identified by the <trdid> and <pid> arguments.
    606  * It can be called by any other thread.
    607  *********************************************************************************************
     478 * It can be called by any other thread in the same process.
     479 ******************************************************************************************
    608480 * @ operation  : operation type as defined below.
    609481 * @ pid        : process identifier.
    610482 * @ trdid      : thread identifier.
    611483 * @ returns O if success / returns -1 if failure.
    612  ********************************************************************************************/
     484 *****************************************************************************************/
    613485int sys_trace( uint32_t operation,
    614486               pid_t    pid,
    615487               uint32_t trdid );
    616488
    617 typedef enum
    618 {
    619     TRACE_ON       = 0,
    620     TRACE_OFF      = 1,
    621 }
    622 trace_operation_t;
     489/******************************************************************************************
     490 * [40] This function returns the hardware platform parameters.
     491 ******************************************************************************************
     492 * @ x_size   : [out] number of clusters in a row.
     493 * @ y_size   : [out] number of clusters in a column.
     494 * @ ncores   : [out] number of cores per cluster.
     495 * @ return 0 if success / return -1 if illegal arguments
     496 *****************************************************************************************/
     497int sys_get_config( uint32_t * x_size,
     498                    uint32_t * y_size,
     499                    uint32_t * ncores );
     500
     501/******************************************************************************************
     502 * [41] This function returns the calling core cluster and local index.
     503 ******************************************************************************************
     504 * @ cxy      : [out] cluster identifier (fixed format)
     505 * @ lid      : [out] core local index in cluster.
     506 * @ return 0 if success / return -1 if illegal arguments
     507 *****************************************************************************************/
     508int sys_get_core( uint32_t * cxy,
     509                  uint32_t * lid );
     510
     511/******************************************************************************************
     512 * [42] This function returns in a 64 bits user buffer the calling core cycles count.
     513 * It uses both the hardware register and the core descriptor cycles count to take
     514 * into account a possible harware register overflow  in 32 bits architectures.
     515 ******************************************************************************************
     516 * cycle    : [out] address of buffer in user space.
     517 * @ return 0 if success / return -1 if illegal arguments
     518 *****************************************************************************************/
     519int sys_get_cycle( uint64_t * cycle );
     520
     521/******************************************************************************************
     522 * [43] This debug function displays on the kernel terminal the current state of a
     523 * scheduler identified by the <cxy> and <lid> arguments.
     524 ******************************************************************************************
     525 * cxy      : [in] target cluster identifier.
     526 * lid      : [in] target core local index.
     527 * @ return 0 if success / return -1 if illegal arguments
     528 *****************************************************************************************/
     529int sys_get_sched( uint32_t  cxy,
     530                   uint32_t  lid );
     531
     532/******************************************************************************************
     533 * [44] This debug function requires the kernel to display on the kernel terminal a message
     534 * containing the thread / process / core identifiers, and the cause of panic,
     535 * as defined by the <string> argument.
     536 ******************************************************************************************
     537 * string   : [in] message to be displayed.
     538 * @ return always 0.
     539 *****************************************************************************************/
     540int sys_panic( char * string );
     541
     542/******************************************************************************************
     543 * [45] This function block the calling thread on the THREAD_BLOCKED_GLOBAL condition,
     544 * and deschedule.
     545 ******************************************************************************************
     546 * @ return 0 if success / returns -1 if failure.
     547 *****************************************************************************************/
     548int sys_thread_sleep();
     549
     550/******************************************************************************************
     551 * [46] This function unblock the thread identified by its <trdid> from the
     552 * THREAD_BLOCKED_GLOBAL condition.
     553 ******************************************************************************************
     554 * @ trdid  : target thread identifier.
     555 * @ return 0 if success / return -1 if failure.
     556 *****************************************************************************************/
     557int sys_thread_wakeup();
    623558
    624559
Note: See TracChangeset for help on using the changeset viewer.