Changeset 539


Ignore:
Timestamp:
Sep 21, 2018, 10:21:42 PM (3 years ago)
Author:
nicolas.van.phan@…
Message:

TTY MUX 4 : Multiplex TTY character sending

Now, when a thread wants to write to a tty,
when the dev_txt_write() or dev_txt_sync_write() are called,
they all call soclib_mtty_aux() with a channel number.
The soclib_mtty_aux() function will write the string char by char,
with each char preceded by the channel number, so that the receiving end
knows to which tty a character is addressed to.

N.B. dev_txt_write() makes *synchronous* writes for the moment
because unlike the vci_tty_tsar, the vci_multi_tty doesn't raise
interrupt except when a new char is received, so we can't use the
interrupt mechanism for writes.

N.B. Now, the TTY DEV threads all write to the same register (WRITE),
but when a thread sends a 2-byte (tty dest. nb. + char), the two must be
send consecutively, without another thread sending a byte in between.
Consequently, a lock has been added to guarantee this atomicity.

Location:
trunk
Files:
4 edited

Legend:

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

    r538 r539  
    4848#endif
    4949
     50extern   chdev_directory_t    chdev_dir;  // allocated in the kernel_init.c file.
     51extern   spinlock_t           txt0_lock;  // Initialized in kernel_init.c
    5052////////////////////////////////////////////////////////////////////////////////////
    5153// These global variables implement the MTTY_RX  FIFOs (one per channel)
     
    538540    char     * buffer = ((txt_sync_args_t *)args)->buffer;
    539541    uint32_t   count  = ((txt_sync_args_t *)args)->count;
     542    uint32_t   channel = ((txt_sync_args_t *)args)->channel;
    540543   
    541544    // get TXT0 chdev cluster and local pointer
     
    554557    xptr_t status_xp = XPTR( tty_cxy , tty_ptr + MTTY_STATUS );
    555558
     559    reg_t  save_sr;
     560
    556561    // loop on characters (busy waiting policy)
    557562    for( i = 0 ; i < count ; i++ )
    558563    {
     564        // This is the MTTY multiplexing
     565        // Before each character, we send the destination TTY number for this char.
     566        // The two bytes (dest number + char) must be sent consecutively,
     567        // so to guarantee this atomicity, we use a lock to prevent other
     568        // concurrent server DEV threads to write a byte in between our two bytes
     569
     570        // Get the lock
     571        spinlock_lock_busy( &txt0_lock, &save_sr );
     572
     573        // Send the destination TTY number
    559574        do
    560575        {
     
    564579
    565580            // transfer one byte if TX buffer empty
     581            if ( empty )  hal_remote_sb( write_xp , channel + '0' );
     582           
     583        }
     584        while ( empty == false );
     585
     586        // Send the character
     587        do
     588        {
     589            // get MTTY_STATUS
     590            status = hal_remote_lw( status_xp );
     591            empty  = ( (status & MTTY_STATUS_TX_FULL) == 0 );
     592
     593            // transfer one byte if TX buffer empty
    566594            if ( empty )  hal_remote_sb( write_xp , buffer[i] );
    567595        }
    568596        while ( empty == false );
     597
     598        // Release the lock
     599        spinlock_unlock_busy( &txt0_lock, save_sr );
    569600    }
    570601}  // end soclib_mtty_aux()
  • trunk/kernel/devices/dev_txt.c

    r527 r539  
    173173#endif
    174174
     175    // get extended pointer on TXT[0] chdev
     176    xptr_t dev_xp = chdev_dir.txt_tx[0];
     177
     178    assert( (dev_xp != XPTR_NULL) , __FUNCTION__ ,
     179    "undefined TXT0 chdev descriptor" );
     180
     181    // get TXTO chdev cluster and local pointer
     182    cxy_t    dev_cxy  = GET_CXY( dev_xp );
     183    chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
     184
     185    // If we use MTTYs (vci_multi_tty), we perform only sync writes
     186    if( dev_ptr->impl == IMPL_TXT_MTY )
     187    {
     188        // get driver command function
     189        dev_aux_t * aux = (dev_aux_t *)hal_remote_lpt( XPTR( dev_cxy , &dev_ptr->aux ) );
     190
     191        // build arguments structure
     192        txt_sync_args_t  args;
     193        args.dev_xp = dev_xp;
     194        args.buffer = buffer;
     195        args.count  = count;
     196        args.channel = channel;
     197
     198        // call driver function
     199        aux( &args );
     200
     201        return 0;
     202    }
     203
     204    // Otherwise, we use vci_tty_tsar so we can use async writes
     205    else
     206    {
    175207    return dev_txt_access( TXT_WRITE , channel , buffer , count );
     208    }
    176209
    177210#if DEBUG_DEV_TXT_TX
     
    238271    args.buffer = buffer;
    239272    args.count  = count;
     273    args.channel = 0;
    240274
    241275    // call driver function
  • trunk/kernel/devices/dev_txt.h

    r534 r539  
    106106    char      * buffer;    /*! local pointer on characters array                         */
    107107    uint32_t    count;     /*! number of characters in buffer                            */
     108    uint32_t    channel;   /*! channel, aka which tty to write to                        */
    108109}
    109110txt_sync_args_t;
  • trunk/kernel/kern/kernel_init.c

    r536 r539  
    8888chdev_t              txt0_chdev                              CONFIG_CACHE_LINE_ALIGNED;
    8989
     90// This variable defines the TXT0 lock for writing characters to MTY0
     91__attribute__((section(".kdata")))
     92spinlock_t           txt0_lock                               CONFIG_CACHE_LINE_ALIGNED;
     93
    9094// This variables define the kernel process0 descriptor
    9195__attribute__((section(".kdata")))
     
    282286    dev_tbl = info->int_dev;
    283287
     288    // Initialize spinlock for writing to MTY0
     289    spinlock_init(&txt0_lock);
     290   
    284291    // Loop on internal peripherals of cluster (0,0) to find MTY0
    285292    for ( i = 0; i < dev_nr; i++ )
Note: See TracChangeset for help on using the changeset viewer.