Changeset 540 for trunk/hal


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

TTY MUX 5/5 : Multiplex TTY character receiving

The multiplexing for receving chars is done by redirecting
the IRQs (when a char is received) to the right chdev (so the right
server DEV thread). When the user types an uppercase letter,
it is treated as a special char used to change the active tty
by redirecting the IRQs to the chdev corresponding to the appropriate
channel.

Add some documentation and example in the code.

Add mfences calls in spinlock_unlock_busy fix a bug on letty physical
hardware.

File:
1 edited

Legend:

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

    r539 r540  
    322322            byte = (char)hal_remote_lb( read_xp );
    323323
     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
    324362            // filter special character ^Z  => block TXT owner process
    325363            if( byte == 0x1A )
     
    533571void __attribute__ ((noinline)) soclib_mtty_aux( void * args )
    534572{
    535     uint32_t   status;
    536     bool_t     empty;
    537     uint32_t   i;
    538 
    539573    xptr_t     dev_xp = ((txt_sync_args_t *)args)->dev_xp;
    540574    char     * buffer = ((txt_sync_args_t *)args)->buffer;
     
    557591    xptr_t status_xp = XPTR( tty_cxy , tty_ptr + MTTY_STATUS );
    558592
    559     reg_t  save_sr;
    560 
    561593    // loop on characters (busy waiting policy)
     594    uint32_t   i;
    562595    for( i = 0 ; i < count ; i++ )
    563596    {
    564597        // This is the MTTY multiplexing
    565         // Before each character, we send the destination TTY number for this char.
     598        // Before each character, we send the destination (RX) TTY number for this char.
    566599        // The two bytes (dest number + char) must be sent consecutively,
    567600        // so to guarantee this atomicity, we use a lock to prevent other
    568601        // concurrent server DEV threads to write a byte in between our two bytes
    569602
    570         // Get the lock
    571         spinlock_lock_busy( &txt0_lock, &save_sr );
    572 
    573603        // Send the destination TTY number
    574         do
    575         {
     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 {
    576623            // get MTTY_STATUS
    577             status = hal_remote_lw( status_xp );
     624            uint32_t status = hal_remote_lw( status_xp );
    578625            empty  = ( (status & MTTY_STATUS_TX_FULL) == 0 );
    579626
    580627            // 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
    594             if ( empty )  hal_remote_sb( write_xp , buffer[i] );
    595         }
    596         while ( empty == false );
    597 
    598         // Release the lock
    599         spinlock_unlock_busy( &txt0_lock, save_sr );
     628            if ( empty ) {
     629                hal_remote_sb( write_xp , buffer[i] );
     630            }
     631        } while ( empty == false );
    600632    }
    601633}  // end soclib_mtty_aux()
Note: See TracChangeset for help on using the changeset viewer.