Ignore:
Timestamp:
Sep 21, 2018, 10:21:42 PM (6 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.

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