Ignore:
Timestamp:
Oct 5, 2018, 12:08:35 AM (6 years ago)
Author:
alain
Message:

Introduction of the soclib_mty driver for the TSAR-LETI architecture.

File:
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/hal/tsar_mips32/drivers/soclib_mty.c

    r562 r570  
    11/*
    2  * soclib_mtty.c - soclib tty driver implementation.
     2 * soclib_mty.c - soclib mty driver implementation.
    33 *
    44 * Author  Alain Greiner (2016,2017,2018)
     
    2626#include <dev_txt.h>
    2727#include <chdev.h>
    28 #include <soclib_mtty.h>
    29 #include <remote_spinlock.h>
     28#include <soclib_mty.h>
    3029#include <thread.h>
    3130#include <printk.h>
    3231#include <hal_special.h>
    3332
    34 #if (DEBUG_SYS_READ & 1)
    35 extern uint32_t  enter_tty_cmd_read;
    36 extern uint32_t  exit_tty_cmd_read;
    37 
    38 extern uint32_t  enter_tty_isr_read;
    39 extern uint32_t  exit_tty_isr_read;
    40 #endif
    41 
    42 #if (DEBUG_SYS_WRITE & 1)
    43 extern uint32_t  enter_tty_cmd_write;
    44 extern uint32_t  exit_tty_cmd_write;
    45 
    46 extern uint32_t  enter_tty_isr_write;
    47 extern uint32_t  exit_tty_isr_write;
    48 #endif
    49 
    5033extern   chdev_directory_t    chdev_dir;  // allocated in the kernel_init.c file.
    51 extern   spinlock_t           txt0_lock;  // Initialized in kernel_init.c
     34
    5235////////////////////////////////////////////////////////////////////////////////////
    53 // These global variables implement the MTTY_RX  FIFOs (one per channel)
     36// These global variables implement the MTY_RX  FIFOs (one per channel)
    5437////////////////////////////////////////////////////////////////////////////////////
    55 
    56 __attribute__((section(".kdata")))
    57 mtty_fifo_t  mtty_rx_fifo[CONFIG_MAX_TXT_CHANNELS];
    58 
    59 __attribute__((section(".kdata")))
    60 mtty_fifo_t  mtty_tx_fifo[CONFIG_MAX_TXT_CHANNELS];
     38// Implementation note:
     39// We allocate - in each cluster - two arrays of FIFOs containing as many entries
     40// as the total number of TXT channels, but all entries are not used in all
     41// clusters: for a given cluster K, a given entry corresponding to a given channel
     42// and a given direction is only used if the associated chdev is in cluster K.
     43// With this policy, the driver can ignore the actual placement of chdevs.
     44////////////////////////////////////////////////////////////////////////////////////
     45
     46__attribute__((section(".kdata")))
     47mty_fifo_t  mty_rx_fifo[CONFIG_MAX_TXT_CHANNELS];
     48
     49__attribute__((section(".kdata")))
     50mty_fifo_t  mty_tx_fifo[CONFIG_MAX_TXT_CHANNELS];
     51
     52////////////////////////////////////////////////////////////////////////////////////
     53// These global variables define the physical channel RX and TX state,
     54// as required by the virtual channels handling.
     55////////////////////////////////////////////////////////////////////////////////////
     56// Implementation note:
     57// These state variables are required, because the ISR is called twice for each
     58// character on the physical channel (for index and value), and does not the same
     59// actions for index and value. They are also used to implement the round-robin
     60// policy between TX_FIFOs.
     61////////////////////////////////////////////////////////////////////////////////////
     62
     63__attribute__((section(".kdata")))
     64bool_t      mty_rx_not_new;                // RX first byte if false
     65
     66__attribute__((section(".kdata")))
     67uint32_t    mty_rx_channel;                // RX virtual channel index
     68
     69__attribute__((section(".kdata")))
     70bool_t      mty_tx_not_new;                // TX first byte if false
     71
     72__attribute__((section(".kdata")))
     73uint32_t    mty_tx_value;                  // TX character ascii value
     74
     75__attribute__((section(".kdata")))
     76uint32_t    mty_tx_last;                   // TX last selected virtual channel
    6177
    6278///////////////////////////////////////
    63 void soclib_mtty_init( chdev_t * chdev )
     79void soclib_mty_init( chdev_t * chdev )
    6480{
    6581    xptr_t reg_xp;
    6682
    6783    // initialise function pointers in chdev
    68     chdev->cmd = &soclib_mtty_cmd;
    69     chdev->isr = &soclib_mtty_isr;
    70     chdev->aux = &soclib_mtty_aux;
    71 
    72     // get TTY channel and extended pointer on TTY peripheral base address
    73     xptr_t   tty_xp  = chdev->base;
     84    chdev->cmd = &soclib_mty_cmd;
     85    chdev->isr = &soclib_mty_isr;
     86    chdev->aux = &soclib_mty_aux;
     87
     88    // get MTY channel and extended pointer on MTY peripheral base address
     89    xptr_t   mty_xp  = chdev->base;
    7490    uint32_t channel = chdev->channel;
    7591    bool_t   is_rx   = chdev->is_rx;
    7692
    77     // get SOCLIB_TTY device cluster and local pointer
    78     cxy_t      tty_cxy = GET_CXY( tty_xp );
    79     uint32_t * tty_ptr = GET_PTR( tty_xp );
    80 
    81     // enable interruptions for RX but not for TX
    82     reg_xp = XPTR( tty_cxy , tty_ptr + MTTY_CONFIG );
    83     hal_remote_sw( reg_xp , MTTY_CONFIG_RX_ENABLE );
     93    // get SOCLIB_MTY device cluster and local pointer
     94    cxy_t      mty_cxy = GET_CXY( mty_xp );
     95    uint32_t * mty_ptr = GET_PTR( mty_xp );
     96
     97    // enable interruptions for RX
     98    reg_xp = XPTR( mty_cxy , mty_ptr + MTY_CONFIG );
     99    hal_remote_s32( reg_xp , MTY_CONFIG_RX_ENABLE );
    84100
    85101    // reset relevant FIFO
    86102    if( is_rx )
    87103    {
    88         mtty_rx_fifo[channel].sts = 0;
    89         mtty_rx_fifo[channel].ptr = 0;
    90         mtty_rx_fifo[channel].ptw = 0;
     104        mty_rx_fifo[channel].sts = 0;
     105        mty_rx_fifo[channel].ptr = 0;
     106        mty_rx_fifo[channel].ptw = 0;
    91107    }
    92108    else
    93109    {
    94         mtty_tx_fifo[channel].sts = 0;
    95         mtty_tx_fifo[channel].ptr = 0;
    96         mtty_tx_fifo[channel].ptw = 0;
     110        mty_tx_fifo[channel].sts = 0;
     111        mty_tx_fifo[channel].ptr = 0;
     112        mty_tx_fifo[channel].ptw = 0;
    97113    }
    98 }  // end soclib_mtty_init()
     114}  // end soclib_mty_init()
    99115
    100116//////////////////////////////////////////////////////////////
    101 void __attribute__ ((noinline)) soclib_mtty_cmd( xptr_t th_xp )
     117void __attribute__ ((noinline)) soclib_mty_cmd( xptr_t th_xp )
    102118{
    103     mtty_fifo_t * fifo;     // MTTY_RX or MTTY_TX FIFO
     119    mty_fifo_t * fifo;     // MTY_RX or MTY_TX FIFO
    104120    char         byte;     // byte value
    105121    uint32_t     done;     // number of bytes moved
     
    110126
    111127    // get command arguments
    112     uint32_t type     = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.type   ) );
    113     xptr_t   buf_xp   = hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.buf_xp ) );
    114     uint32_t count    = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.count  ) );
     128    uint32_t type     = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->txt_cmd.type   ) );
     129    xptr_t   buf_xp   = hal_remote_l64( XPTR( th_cxy , &th_ptr->txt_cmd.buf_xp ) );
     130    uint32_t count    = hal_remote_l32 ( XPTR( th_cxy , &th_ptr->txt_cmd.count  ) );
    115131    xptr_t   error_xp = XPTR( th_cxy , &th_ptr->txt_cmd.error );
    116132
    117 #if (DEBUG_SYS_READ & 1)
    118 if( type == TXT_READ) enter_tty_cmd_read = (uint32_t)hal_get_cycles();
    119 #endif
    120 
    121 #if (DEBUG_SYS_WRITE & 1)
    122 if( type == TXT_WRITE) enter_tty_cmd_write = (uint32_t)hal_get_cycles();
    123 #endif
    124 
    125133    // get TXT device cluster and pointers
    126     xptr_t     dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) );
     134    xptr_t     dev_xp = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) );
    127135    cxy_t      dev_cxy = GET_CXY( dev_xp );
    128136    chdev_t  * dev_ptr = GET_PTR( dev_xp );
    129137
    130     // get cluster and pointers for SOCLIB_TTY peripheral base segment
    131     xptr_t     tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
    132     cxy_t      tty_cxy = GET_CXY( tty_xp );
    133     uint32_t * tty_ptr = GET_PTR( tty_xp );
    134 
    135     // get TTY channel index and channel base address
    136     uint32_t   channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) );
    137     uint32_t * base    = tty_ptr;
     138    // get MTY channel index and channel base address
     139    uint32_t   channel = hal_remote_l32( XPTR( dev_cxy , &dev_ptr->channel ) );
    138140
    139141    ///////////////////////
    140     if( type == TXT_WRITE )         // write bytes to MTTY_TX FIFO
    141     {
    142         fifo = &mtty_tx_fifo[channel];
     142    if( type == TXT_WRITE )         // write bytes to MTY_TX FIFO
     143    {
     144        fifo = &mty_tx_fifo[channel];
    143145
    144146        done = 0;
     
    146148        while( done < count )
    147149        {
    148             if( fifo->sts < MTTY_FIFO_DEPTH )   // put one byte to FIFO if TX_FIFO not full
     150            if( fifo->sts < MTY_FIFO_DEPTH )   // put one byte to FIFO if TX_FIFO not full
    149151            {
    150152                // get one byte from command buffer
     
    164166
    165167                // update FIFO state
    166                 fifo->ptw = (fifo->ptw + 1) % MTTY_FIFO_DEPTH;
     168                fifo->ptw = (fifo->ptw + 1) % MTY_FIFO_DEPTH;
    167169                hal_atomic_add( &fifo->sts , 1 );
    168170
    169171                // udate number of bytes moved
    170172                done++;
    171 
    172                 // enable TX_IRQ
    173                 //      vci_multi_tty devices never raise TX IRQs
    174                 //      so the following instructions are useless
    175                 //      and moreover they kernel panic
    176                 // xptr_t config_xp = XPTR( tty_cxy , base + MTTY_CONFIG );
    177                 // uint32_t old = hal_remote_lw( config_xp );
    178                 // uint32_t new = old | MTTY_CONFIG_TX_ENABLE;
    179                 // hal_remote_atomic_cas( config_xp , old , new );
    180                 // hal_remote_sw( XPTR( tty_cxy , base + MTTY_CONFIG ) , MTTY_CONFIG_TX_ENABLE );
    181173            }
    182174            else                                // block & deschedule if TX_FIFO full
     
    186178
    187179                // deschedule
    188                 sched_yield( "MTTY_TX_FIFO full" );
     180                sched_yield( "MTY_TX_FIFO full" );
    189181            }
    190182        }
    191183
    192184        // set error status in command and return
    193         hal_remote_sw( error_xp , 0 );
     185        hal_remote_s32( error_xp , 0 );
    194186    }
    195187    ///////////////////////////
    196     else if( type == TXT_READ )       // read bytes from MTTY_RX FIFO   
    197     {
    198         fifo = &mtty_rx_fifo[channel];
     188    else if( type == TXT_READ )       // read bytes from MTY_RX FIFO   
     189    {
     190        fifo = &mty_rx_fifo[channel];
    199191
    200192        done = 0;
     
    214206#endif
    215207                // update FIFO state
    216                 fifo->ptr = (fifo->ptr + 1) % MTTY_FIFO_DEPTH;
     208                fifo->ptr = (fifo->ptr + 1) % MTY_FIFO_DEPTH;
    217209                hal_atomic_add( &fifo->sts , -1 );
    218210
     
    229221   
    230222                // deschedule
    231                 sched_yield( "MTTY_RX_FIFO empty" );
     223                sched_yield( "MTY_RX_FIFO empty" );
    232224            }
    233225        }  // end while
    234226
    235227        // set error status in command
    236         hal_remote_sw( error_xp , 0 );
     228        hal_remote_s32( error_xp , 0 );
    237229    }
    238230    else
     
    241233    }
    242234
    243 #if (DEBUG_SYS_READ & 1)
    244 if( type == TXT_READ ) exit_tty_cmd_read = (uint32_t)hal_get_cycles();
    245 #endif
    246 
    247 #if (DEBUG_SYS_WRITE & 1)
    248 if( type == TXT_WRITE ) exit_tty_cmd_write = (uint32_t)hal_get_cycles();
    249 #endif
    250 
    251 }  // end soclib_mtty_cmd()
     235}  // end soclib_mty_cmd()
    252236
    253237/////////////////////////////////////////////////////////////////
    254 void __attribute__ ((noinline)) soclib_mtty_isr( chdev_t * chdev )
     238void __attribute__ ((noinline)) soclib_mty_isr( chdev_t * chdev )
    255239{
    256240    thread_t   * server;            // pointer on TXT chdev server thread
    257241    lid_t        server_lid;        // local index of core running the server thread
    258     uint32_t     channel;           // TXT chdev channel
     242    uint32_t     channel;           // TXT chdev channel (virtual channel index)
    259243    bool_t       is_rx;             // TXT chdev direction
    260244    char         byte;              // byte value
     
    263247    process_t  * owner_ptr;         // local pointer on TXT owner process
    264248    pid_t        owner_pid;         // TXT owner process identifier
    265     mtty_fifo_t * fifo;              // pointer on MTTY_TX or MTTY_RX FIFO
    266     cxy_t        tty_cxy;           // soclib_mtty cluster
    267     uint32_t   * tty_ptr;           // soclib_mtty segment base address
    268     uint32_t   * base;              // soclib_mtty channel base address
    269     xptr_t       status_xp;         // extended pointer on MTTY_STATUS register
    270     xptr_t       write_xp;          // extended pointer on MTTY_WRITE register
    271     xptr_t       read_xp;           // extended pointer on MTTY_READ register
     249    mty_fifo_t * fifo;              // pointer on MTY_TX or MTY_RX FIFO
     250    cxy_t        mty_cxy;           // soclib_mty cluster
     251    uint32_t   * mty_ptr;           // soclib_mty segment base address
     252    xptr_t       status_xp;         // extended pointer on MTY_STATUS register
     253    xptr_t       write_xp;          // extended pointer on MTY_WRITE register
     254    xptr_t       read_xp;           // extended pointer on MTY_READ register
    272255    xptr_t       parent_xp;         // extended pointer on parent process
    273256    cxy_t        parent_cxy;        // parent process cluster
    274257    process_t  * parent_ptr;        // local pointer on parent process
    275     xptr_t       children_lock_xp;  // extended pointer on children processes lock
    276258    thread_t   * parent_main_ptr;   // extended pointer on parent process main thread
    277259    xptr_t       parent_main_xp;    // local pointer on parent process main thread
     260    uint32_t     n;                 // index in loop
     261    bool_t       found;
     262
     263#if DEBUG_HAL_TXT_RX
     264uint32_t rx_cycle = (uint32_t)hal_get_cycles();
     265#endif
     266
     267#if DEBUG_HAL_TXT_TX
     268uint32_t tx_cycle = (uint32_t)hal_get_cycles();
     269#endif
    278270
    279271    // get TXT chdev channel, direction and server thread
    280     channel    = chdev->channel;
    281272    is_rx      = chdev->is_rx;
    282273    server     = chdev->server;
    283274    server_lid = server->core->lid;
    284275
    285 #if (DEBUG_SYS_READ & 1)
    286 if( is_rx ) enter_tty_isr_read = (uint32_t)hal_get_cycles();
    287 #endif
    288 
    289 #if (DEBUG_SYS_WRITE & 1)
    290 if( is_rx == 0 ) enter_tty_isr_write = (uint32_t)hal_get_cycles();
    291 #endif
    292 
    293 #if DEBUG_HAL_TXT_RX
    294 uint32_t rx_cycle = (uint32_t)hal_get_cycles();
    295 #endif
    296 
    297 #if DEBUG_HAL_TXT_TX
    298 uint32_t tx_cycle = (uint32_t)hal_get_cycles();
    299 #endif
    300 
    301     // get SOCLIB_TTY peripheral cluster and local pointer
    302     tty_cxy = GET_CXY( chdev->base );
    303     tty_ptr = GET_PTR( chdev->base );
    304 
    305     // get channel base address
    306     base    = tty_ptr;
    307 
    308     // get extended pointer on TTY registers
    309     status_xp = XPTR( tty_cxy , base + MTTY_STATUS );
    310     write_xp  = XPTR( tty_cxy , base + MTTY_WRITE );
    311     read_xp   = XPTR( tty_cxy , base + MTTY_READ );
     276    // get SOCLIB_MTY peripheral cluster and local pointer
     277    mty_cxy = GET_CXY( chdev->base );
     278    mty_ptr = GET_PTR( chdev->base );
     279
     280    // get extended pointer on MTY registers
     281    status_xp = XPTR( mty_cxy , mty_ptr + MTY_STATUS );
     282    write_xp  = XPTR( mty_cxy , mty_ptr + MTY_WRITE );
     283    read_xp   = XPTR( mty_cxy , mty_ptr + MTY_READ );
    312284
    313285    /////////////////////////// handle RX //////////////////////
    314286    if( is_rx )
    315287    {
    316         fifo = &mtty_rx_fifo[channel];
    317 
    318         // try to move bytes until MTTY_READ register empty
    319         while( hal_remote_lw( status_xp ) & MTTY_STATUS_RX_FULL )   
     288        // check one byte available in MTY_READ register
     289        if( hal_remote_l32( status_xp ) & MTY_STATUS_RX_FULL )   
    320290        {
    321             // get one byte from MTTY_READ register & acknowledge RX_IRQ
     291            // get one byte from MTY_READ register & acknowledge RX_IRQ
    322292            byte = (char)hal_remote_lb( read_xp );
    323293
    324             // Ignore Carriage Returns
    325             if( byte == 0xD )
    326             {
    327                 continue;
    328             }
    329 
    330             // This is the MTTY multiplexing
    331             // When a extended ASCII char are received (typing Ctrl-Shift-U then 100+n for example on the terminal)
    332             // Two characters are received : 0xFFFFFFc4 then 0xFFFFFF80 + n
    333             // When this second char is received, it is considered a metachar that determines the tty dest number
    334             // Thus, if you want to make tty 5 the new target, type Ctrl+Shift+U then 105
    335             // Now all keystrokes IRQs will be handled by the server DEV thread
    336             // associated to RX channel number 5
    337             if( (byte & 0xFF) > 0x80 && (byte & 0xFF) <= 0x89 )
    338             {
    339                 // Disable MTTY IRQ for the core owning
    340                 // the current channel's server DEV thread
    341                 dev_pic_disable_irq( server_lid, XPTR( local_cxy , chdev ) );
    342                
    343                 int         tty_destnb  = (int)(byte & 0xFF) - 0x80;
    344                 chdev_t *   new_chdev   = chdev_dir.txt_rx[tty_destnb];
    345                 lid_t       new_lid     = new_chdev->server->core->lid;
    346 
    347                 // Bind MTTY IRQ to the core owning the new channel's server DEV thread
    348                 dev_pic_bind_irq( new_lid , new_chdev );               
    349 
    350                 // Enable MTTY IRQ for the core owning
    351                 // the new channel's server DEV thread
    352                 dev_pic_enable_irq( new_lid , XPTR( local_cxy , new_chdev ) );
    353 
    354                 channel    = new_chdev->channel;
    355                 is_rx      = new_chdev->is_rx;
    356                 server     = new_chdev->server;
    357                 server_lid = new_lid;
    358                 fifo = &mtty_rx_fifo[channel];
    359                 continue;
    360             }
    361 
    362             // filter special character ^Z  => block TXT owner process
    363             if( byte == 0x1A )
    364             {
     294            // test physical RX channel state
     295            if( mty_rx_not_new == false )      // get first byte (virtual channel index)
     296            {
     297                // register virtual channel index
     298                mty_rx_channel = (uint32_t)byte;
     299
     300                // update physical RX channel state
     301                mty_rx_not_new = true;
     302            }
     303            else                               // get second byte (character value)
     304            {
     305                // get virtual channel index registered
     306                channel = mty_rx_channel;
     307
     308                // get destination TX_FIFO
     309                fifo = &mty_rx_fifo[channel];
     310
     311                // filter special character ^Z  => block TXT owner process
     312                if( byte == 0x1A )
     313                {
    365314
    366315#if DEBUG_HAL_TXT_RX
     
    368317printk("\n[DBG] %s : read ^Z character from TXT%d\n", __FUNCTION__, channel );
    369318#endif
    370                 // get pointers on TXT owner process in owner cluster
    371                 owner_xp  = process_txt_get_owner( channel );
     319                    // get pointers on TXT owner process in owner cluster
     320                    owner_xp  = process_txt_get_owner( channel );
    372321               
    373                 // check process exist
    374                 assert( (owner_xp != XPTR_NULL) , __FUNCTION__,
    375                 "TXT owner process not found\n" );
    376 
    377                 // get relevant infos on TXT owner process
    378                 owner_cxy = GET_CXY( owner_xp );
    379                 owner_ptr = GET_PTR( owner_xp );
    380                 owner_pid = hal_remote_lw( XPTR( owner_cxy , &owner_ptr->pid ) );
    381 
    382                 // block TXT owner process only if it is not the INIT process
    383                 if( owner_pid != 1 )
     322                    // check process exist
     323                    assert( (owner_xp != XPTR_NULL) , __FUNCTION__,
     324                    "TXT owner process not found\n" );
     325
     326                    // get relevant infos on TXT owner process
     327                    owner_cxy = GET_CXY( owner_xp );
     328                    owner_ptr = GET_PTR( owner_xp );
     329                    owner_pid = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->pid ) );
     330
     331                    // block TXT owner process only if it is not the INIT process
     332                    if( owner_pid != 1 )
     333                    {
     334                        // get parent process descriptor pointers
     335                        parent_xp = hal_remote_l64( XPTR( owner_cxy ,
     336                                                    &owner_ptr->parent_xp ) );
     337                        parent_cxy = GET_CXY( parent_xp );
     338                        parent_ptr = GET_PTR( parent_xp );
     339
     340                        // get pointers on the parent process main thread
     341                        parent_main_ptr = hal_remote_lpt( XPTR(parent_cxy,
     342                                                          &parent_ptr->th_tbl[0]));
     343                        parent_main_xp  = XPTR( parent_cxy , parent_main_ptr );
     344
     345                        // transfer TXT ownership
     346                        process_txt_transfer_ownership( owner_xp );
     347
     348                        // block all threads in all clusters, but the main thread
     349                        process_sigaction( owner_pid , BLOCK_ALL_THREADS );
     350
     351                        // block the main thread
     352                        xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );
     353                        thread_block( main_xp , THREAD_BLOCKED_GLOBAL );
     354
     355                        // atomically update owner process termination state
     356                        hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
     357                                              PROCESS_TERM_STOP );
     358
     359                        // take the children lock and unblock the parent process main thread
     360                        thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
     361
     362                        return;
     363                    }
     364                }
     365
     366                // filter special character ^C  => kill TXT owner process
     367                if( byte == 0x03 )
    384368                {
    385                     // get parent process descriptor pointers
    386                     parent_xp  = hal_remote_lwd( XPTR( owner_cxy , &owner_ptr->parent_xp ) );
    387                     parent_cxy = GET_CXY( parent_xp );
    388                     parent_ptr = GET_PTR( parent_xp );
    389 
    390                     // get extended pointer on lock protecting children list in parent process
    391                     children_lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock );
    392 
    393                     // get pointers on the parent process main thread
    394                     parent_main_ptr = hal_remote_lpt(XPTR(parent_cxy,&parent_ptr->th_tbl[0]));
    395                     parent_main_xp  = XPTR( parent_cxy , parent_main_ptr );
    396 
    397                     // transfer TXT ownership
    398                     process_txt_transfer_ownership( owner_xp );
    399 
    400                     // block all threads in all clusters, but the main thread
    401                     process_sigaction( owner_pid , BLOCK_ALL_THREADS );
    402 
    403                     // block the main thread
    404                     xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );
    405                     thread_block( main_xp , THREAD_BLOCKED_GLOBAL );
    406 
    407                     // atomically update owner process termination state
    408                     hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
    409                                           PROCESS_TERM_STOP );
    410 
    411                     // take the children lock and unblock the parent process main thread
    412                     remote_spinlock_lock( children_lock_xp );
    413                     thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
    414                     remote_spinlock_unlock( children_lock_xp );
    415 
    416                     return;
    417                 }
    418             }
    419 
    420             // filter special character ^C  => kill TXT owner process
    421             if( byte == 0x03 )
    422             {
    423369
    424370#if DEBUG_HAL_TXT_RX
     
    426372printk("\n[DBG] %s : read ^C character from TXT%d\n", __FUNCTION__, channel );
    427373#endif
    428                 // get pointer on TXT owner process in owner cluster
    429                 owner_xp  = process_txt_get_owner( channel );
    430 
    431                 // check process exist
    432                 assert( (owner_xp != XPTR_NULL) , __FUNCTION__,
    433                 "TXT owner process not found\n" );
    434 
    435                 // get relevant infos on TXT owner process
    436                 owner_cxy = GET_CXY( owner_xp );
    437                 owner_ptr = GET_PTR( owner_xp );
    438                 owner_pid = hal_remote_lw( XPTR( owner_cxy , &owner_ptr->pid ) );
    439 
    440                 // kill TXT owner process only if it is not the INIT process
    441                 if( owner_pid != 1 )
     374                    // get pointer on TXT owner process in owner cluster
     375                    owner_xp  = process_txt_get_owner( channel );
     376
     377                    // check process exist
     378                    assert( (owner_xp != XPTR_NULL) , __FUNCTION__,
     379                    "TXT owner process not found\n" );
     380
     381                    // get relevant infos on TXT owner process
     382                    owner_cxy = GET_CXY( owner_xp );
     383                    owner_ptr = GET_PTR( owner_xp );
     384                    owner_pid = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->pid ) );
     385
     386                    // kill TXT owner process only if it is not the INIT process
     387                    if( owner_pid != 1 )
     388                    {
     389                        // get parent process descriptor pointers
     390                        parent_xp  = hal_remote_l64( XPTR( owner_cxy,
     391                                                     &owner_ptr->parent_xp ) );
     392                        parent_cxy = GET_CXY( parent_xp );
     393                        parent_ptr = GET_PTR( parent_xp );
     394
     395                        // get pointers on the parent process main thread
     396                        parent_main_ptr = hal_remote_lpt( XPTR( parent_cxy,
     397                                                          &parent_ptr->th_tbl[0]));
     398                        parent_main_xp  = XPTR( parent_cxy , parent_main_ptr );
     399
     400                        // remove process from TXT list
     401                        process_txt_detach( owner_xp );
     402
     403                        // mark for delete all thread in all clusters, but the main
     404                        process_sigaction( owner_pid , DELETE_ALL_THREADS );
     405               
     406                        // block main thread
     407                        xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );
     408                        thread_block( main_xp , THREAD_BLOCKED_GLOBAL );
     409
     410                        // atomically update owner process termination state
     411                        hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
     412                                              PROCESS_TERM_KILL );
     413
     414                        // take the children lock and unblock the parent process main thread
     415                        thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
     416
     417                        return;
     418                    }
     419                }
     420
     421                // write byte in RX FIFO if not full / discard byte if full
     422                if ( fifo->sts < MTY_FIFO_DEPTH )
    442423                {
    443                     // get parent process descriptor pointers
    444                     parent_xp  = hal_remote_lwd( XPTR( owner_cxy , &owner_ptr->parent_xp ) );
    445                     parent_cxy = GET_CXY( parent_xp );
    446                     parent_ptr = GET_PTR( parent_xp );
    447 
    448                     // get extended pointer on lock protecting children list in parent process
    449                     children_lock_xp = XPTR( parent_cxy , &parent_ptr->children_lock );
    450 
    451                     // get pointers on the parent process main thread
    452                     parent_main_ptr = hal_remote_lpt(XPTR(parent_cxy,&parent_ptr->th_tbl[0]));
    453                     parent_main_xp  = XPTR( parent_cxy , parent_main_ptr );
    454 
    455                     // remove process from TXT list
    456                     process_txt_detach( owner_xp );
    457 
    458                     // mark for delete all thread in all clusters, but the main
    459                     process_sigaction( owner_pid , DELETE_ALL_THREADS );
    460                
    461                     // block main thread
    462                     xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );
    463                     thread_block( main_xp , THREAD_BLOCKED_GLOBAL );
    464 
    465                     // atomically update owner process termination state
    466                     hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
    467                                           PROCESS_TERM_KILL );
    468 
    469                     // take the children lock and unblock the parent process main thread
    470                     remote_spinlock_lock( children_lock_xp );
    471                     thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT );
    472                     remote_spinlock_unlock( children_lock_xp );
    473 
    474                     return;
    475                 }
    476             }
    477 
    478             // write byte in MTTY_RX FIFO if not full / discard byte if full
    479             if ( fifo->sts < MTTY_FIFO_DEPTH )
    480             {
    481424
    482425#if DEBUG_HAL_TXT_RX
     
    485428__FUNCTION__, byte, channel );
    486429#endif
    487                 // store byte into FIFO
    488                 fifo->data[fifo->ptw] = (char)byte;
    489 
    490                 // avoid race
    491                 hal_fence();
    492 
    493                 // update RX_FIFO state
    494                 fifo->ptw = (fifo->ptw + 1) % MTTY_FIFO_DEPTH;
    495                 hal_atomic_add( &fifo->sts , 1 );
    496 
    497                 // unblock TXT_RX server thread
    498                 thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR );
    499 
    500                 // send IPI to core running server thread
    501                 dev_pic_send_ipi( local_cxy , server_lid );
    502             }
    503             else
    504             {
    505                 printk("\n[WARNING] %s : MTTY_RX_FIFO[%d] full => discard character <%x>\n",
    506                 __FUNCTION__, channel, (uint32_t)byte );
    507             }
    508         }  // end while MTTY_READ register full
    509 
     430                    // store byte into FIFO
     431                    fifo->data[fifo->ptw] = (char)byte;
     432
     433                    // avoid race
     434                    hal_fence();
     435
     436                    // update RX_FIFO state
     437                    fifo->ptw = (fifo->ptw + 1) % MTY_FIFO_DEPTH;
     438                    hal_atomic_add( &fifo->sts , 1 );
     439
     440                    // unblock TXT_RX server thread
     441                    thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR );
     442
     443                    // send IPI to core running server thread
     444                    dev_pic_send_ipi( local_cxy , server_lid );
     445                }
     446                else
     447                {
     448                    printk("\n[WARNING] %s : MTY_RX_FIFO[%d] full => discard char <%x>\n",
     449                    __FUNCTION__, channel, (uint32_t)byte );
     450                }
     451
     452                // update physical RX channel state
     453                mty_rx_not_new = true;
     454
     455            }  // end get character value
     456        }  // end if byte available in MTY_READ register
    510457    }  // end RX
    511458
     
    513460    else
    514461    {
    515         fifo = &mtty_tx_fifo[channel];
    516 
    517         // try to move bytes until TX_FIFO empty
    518         while( fifo->sts > 0 )
     462        // test physical TX channel state
     463        if( mty_tx_not_new == false )      // send first byte (virtual channel index)
    519464        {
    520             // write one byte to MTTY_WRITE register if empty / exit loop if full
    521             if( (hal_remote_lw( status_xp ) & MTTY_STATUS_TX_FULL) == 0 )
    522             {
    523                 // get one byte from TX_FIFO
     465            // scan the set of the TX_FIFO
     466            for( n = 0 , found = false ; n < CONFIG_MAX_TXT_CHANNELS ; n++ )
     467            {
     468                // implement round-robin policy
     469                channel = (n + mty_tx_last + 1) % CONFIG_MAX_TXT_CHANNELS;
     470
     471                // get pointer on TX_FIFO[channel]
     472                fifo = &mty_tx_fifo[channel];
     473
     474                if( fifo->sts > 0 )
     475                {
     476                    found = true;
     477                    break;
     478                }
     479            }
     480
     481            // get one byte from TX_FIFO if found and send channel index
     482            if( found )
     483            {
     484                // get one byte from selected TX_FIFO
    524485                byte = fifo->data[fifo->ptr];
    525486
     
    530491#endif
    531492                // update TX_FIFO state
    532                 fifo->ptr = (fifo->ptr + 1) % MTTY_FIFO_DEPTH;
     493                fifo->ptr = (fifo->ptr + 1) % MTY_FIFO_DEPTH;
    533494                hal_atomic_add( &fifo->sts , -1 );
    534495
    535                 // write byte to MTTY_WRITE register & acknowledge TX_IRQ
    536                 hal_remote_sb( write_xp , byte );
     496                // update TX physical channel state
     497                mty_tx_value   = (uint32_t)byte;
     498                mty_tx_not_new = true;
     499                mty_tx_last    = channel;
     500
     501                // write virtual channel index to TX_WRITE register
     502                hal_remote_sb( write_xp , (uint8_t)channel );
     503
     504                // unblock TXT_TX server thread
     505                thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR );
     506
     507                // send IPI to core running server thread
     508                dev_pic_send_ipi( local_cxy , server_lid );
    537509            }
    538510        }
    539 
    540         // disable TX_IRQ
    541         //      vci_multi_tty devices never raise TX IRQs
    542         //      so the following instructions are useless
    543         //      and moreover they kernel panic
    544         // xptr_t config_xp = XPTR( tty_cxy , base + MTTY_CONFIG );
    545         // uint32_t old = hal_remote_lw( config_xp );
    546         // uint32_t new = old & ~(MTTY_CONFIG_TX_ENABLE);
    547         // hal_remote_atomic_cas( config_xp , old , new );
    548         // hal_remote_sw( XPTR( tty_cxy , base + MTTY_CONFIG ) , 0 );
    549 
    550         // unblock TXT_TX server thread
    551         thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR );
    552 
    553         // send IPI to core running server thread
    554         dev_pic_send_ipi( local_cxy , server_lid );
    555 
     511        else                             // send second byte (character value)
     512        {
     513            // write registered character value to TX_WRITE register
     514            hal_remote_sb( write_xp , (uint8_t)mty_tx_value );
     515
     516            // update TX physical channel state
     517            mty_tx_not_new = false;
     518        }  // end if MTY_WRITE register empty
    556519    }  // end TX
    557520
    558521    hal_fence();
    559522
    560 #if (DEBUG_SYS_READ & 1)
    561 if( is_rx ) exit_tty_isr_read = (uint32_t)hal_get_cycles();
    562 #endif
    563 
    564 #if (DEBUG_SYS_WRITE & 1)
    565 if( is_rx == 0 ) exit_tty_isr_write = (uint32_t)hal_get_cycles();
    566 #endif
    567 
    568 }  // end soclib_mtty_isr()
     523}  // end soclib_mty_isr()
    569524
    570525/////////////////////////////////////////////////////////////
    571 void __attribute__ ((noinline)) soclib_mtty_aux( void * args )
     526void __attribute__ ((noinline)) soclib_mty_aux( void * args )
    572527{
    573     xptr_t     dev_xp = ((txt_sync_args_t *)args)->dev_xp;
    574     char     * buffer = ((txt_sync_args_t *)args)->buffer;
    575     uint32_t   count  = ((txt_sync_args_t *)args)->count;
    576     uint32_t   channel = ((txt_sync_args_t *)args)->channel;
     528    uint32_t   i;
     529
     530    xptr_t       dev_xp  = ((txt_sync_args_t *)args)->dev_xp;
     531    const char * buffer  = ((txt_sync_args_t *)args)->buffer;
     532    uint32_t     count   = ((txt_sync_args_t *)args)->count;
     533    uint32_t     channel = ((txt_sync_args_t *)args)->channel;
    577534   
    578     // get TXT0 chdev cluster and local pointer
     535    // get chdev cluster and local pointer
    579536    cxy_t     dev_cxy = GET_CXY( dev_xp );
    580     chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    581 
    582     // get extended pointer on TTY channel base address
    583     xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
    584 
    585     // get TTY channel segment cluster and local pointer
    586     cxy_t      tty_cxy = GET_CXY( tty_xp );
    587     uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );
    588 
    589     // get extended pointers on MTTY_WRITE & MTTY_STATUS registers
    590     xptr_t write_xp  = XPTR( tty_cxy , tty_ptr + MTTY_WRITE );
    591     xptr_t status_xp = XPTR( tty_cxy , tty_ptr + MTTY_STATUS );
    592 
    593     // loop on characters (busy waiting policy)
    594     uint32_t   i;
     537    chdev_t * dev_ptr = GET_PTR( dev_xp );
     538
     539    // get extended pointer on MTY channel base address
     540    xptr_t mty_xp = (xptr_t)hal_remote_l64( XPTR( dev_cxy , &dev_ptr->base ) );
     541
     542    // get MTY channel segment cluster and local pointer
     543    cxy_t      mty_cxy = GET_CXY( mty_xp );
     544    uint32_t * mty_ptr = GET_PTR( mty_xp );
     545
     546    // get extended pointers on MTY_WRITE & MTY_STATUS registers
     547    xptr_t write_xp  = XPTR( mty_cxy , mty_ptr + MTY_WRITE );
     548    xptr_t status_xp = XPTR( mty_cxy , mty_ptr + MTY_STATUS );
     549
     550    // loop on characters (two bytes per character)
    595551    for( i = 0 ; i < count ; i++ )
    596552    {
    597         // This is the MTTY multiplexing
    598         // Before each character, we send the destination (RX) TTY number for this char.
    599         // The two bytes (dest number + char) must be sent consecutively,
    600         // so to guarantee this atomicity, we use a lock to prevent other
    601         // concurrent server DEV threads to write a byte in between our two bytes
    602 
    603         // Send the destination TTY number
    604         // HACK: Remove this on the Lety physical prototype.
    605         // This 'if' is here so that the kernel messages in simulation are readable
    606         bool_t empty = false;
    607         if (channel > 0) {
    608             // For examples, "Hello" would appear "0H0e0l0l0o" on the simulation terminal
    609             do {
    610                 // get MTTY_STATUS
    611                 uint32_t status = hal_remote_lw( status_xp );
    612                 empty  = ( (status & MTTY_STATUS_TX_FULL) == 0 );
    613 
    614                 // transfer one byte if TX buffer empty
    615                 if ( empty ) {
    616                     hal_remote_sb( write_xp , channel + '0' );
    617                 }
    618             } while ( empty == false );
    619         }
    620 
    621         // Send the character
    622         do {
    623             // get MTTY_STATUS
    624             uint32_t status = hal_remote_lw( status_xp );
    625             empty  = ( (status & MTTY_STATUS_TX_FULL) == 0 );
    626 
    627             // transfer one byte if TX buffer empty
    628             if ( empty ) {
    629                 hal_remote_sb( write_xp , buffer[i] );
    630             }
    631         } while ( empty == false );
     553        // write virtual channel index to MTY_WRITE register
     554        hal_remote_sb( write_xp , (uint8_t)channel );
     555
     556        // write character value to MTY_WRITE register
     557        hal_remote_sb( write_xp , buffer[i] );
    632558    }
    633 }  // end soclib_mtty_aux()
    634 
    635 
    636 
     559}  // end soclib_mty_aux()
     560
     561
     562
Note: See TracChangeset for help on using the changeset viewer.