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

First implementation of fork/exec.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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()
Note: See TracChangeset for help on using the changeset viewer.