Changeset 436 for trunk/hal/tsar_mips32


Ignore:
Timestamp:
Mar 7, 2018, 9:02:03 AM (7 years ago)
Author:
alain
Message:

1) improve the threads and process destruction mechanism.
2) introduce FIFOs in the soclib_tty driver.

Location:
trunk/hal/tsar_mips32/drivers
Files:
5 edited

Legend:

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

    r408 r436  
    132132    else                                            // descheduling + IRQ policy
    133133    {
    134         thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
     134        thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR );
    135135        sched_yield("blocked on ISR");
    136136
     
    173173
    174174    // unblock server thread
    175     thread_unblock( server_xp , THREAD_BLOCKED_DEV_ISR );
     175    thread_unblock( server_xp , THREAD_BLOCKED_ISR );
    176176
    177177    // unblock client thread
  • trunk/hal/tsar_mips32/drivers/soclib_dma.c

    r408 r436  
    9090
    9191    // Block and deschedule server thread
    92     thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
     92    thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR );
    9393    sched_yield("blocked on ISR");
    9494   
     
    127127
    128128    // unblock server thread
    129     thread_unblock( server_xp , THREAD_BLOCKED_DEV_ISR );
     129    thread_unblock( server_xp , THREAD_BLOCKED_ISR );
    130130
    131131    // unblock client thread
  • trunk/hal/tsar_mips32/drivers/soclib_hba.c

    r408 r436  
    239239    else                                           // descheduling + IRQ
    240240    {
    241         thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
     241        thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR );
    242242        sched_yield( "blocked on ISR" );
    243243    }
  • trunk/hal/tsar_mips32/drivers/soclib_tty.c

    r435 r436  
    4646#endif
    4747
     48////////////////////////////////////////////////////////////////////////////////////
     49// These global variables implement the TTY_RX  FIFOs (one per channel)
     50////////////////////////////////////////////////////////////////////////////////////
     51
     52__attribute__((section(".kdata")))
     53tty_fifo_t  tty_rx_fifo[CONFIG_MAX_TXT_CHANNELS];
     54
     55__attribute__((section(".kdata")))
     56tty_fifo_t  tty_tx_fifo[CONFIG_MAX_TXT_CHANNELS];
     57
    4858///////////////////////////////////////
    4959void soclib_tty_init( chdev_t * chdev )
     
    5161    xptr_t reg_xp;
    5262
     63    // initialise function pointers in chdev
    5364    chdev->cmd = &soclib_tty_cmd;
    5465    chdev->isr = &soclib_tty_isr;
     
    5869    xptr_t   tty_xp  = chdev->base;
    5970    uint32_t channel = chdev->channel;
     71    bool_t   is_rx   = chdev->is_rx;
    6072
    6173    // get SOCLIB_TTY device cluster and local pointer
     
    7082    reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_TX_IRQ_ENABLE );
    7183    hal_remote_sw( reg_xp , 0 );
    72 }
     84
     85    // reset relevant FIFO
     86    if( is_rx )
     87    {
     88        tty_rx_fifo[channel].sts = 0;
     89        tty_rx_fifo[channel].ptr = 0;
     90        tty_rx_fifo[channel].ptw = 0;
     91    }
     92    else
     93    {
     94        tty_tx_fifo[channel].sts = 0;
     95        tty_tx_fifo[channel].ptr = 0;
     96        tty_tx_fifo[channel].ptw = 0;
     97    }
     98}  // end soclib_tty_init()
    7399
    74100//////////////////////////////////////////////////////////////
    75101void __attribute__ ((noinline)) soclib_tty_cmd( xptr_t th_xp )
    76102{
    77 
    78 #if (CONFIG_DEBUG_SYS_READ & 1)
    79 if( type == TXT_READ) enter_tty_cmd_read = (uint32_t)hal_get_cycles();
    80 #endif
    81 
    82 #if (CONFIG_DEBUG_SYS_WRITE & 1)
    83 if( type == TXT_WRITE) enter_tty_cmd_write = (uint32_t)hal_get_cycles();
    84 #endif
     103    tty_fifo_t * fifo;     // TTY_RX or TTY_TX FIFO
     104    char         byte;     // byte value
     105    uint32_t     done;     // number of bytes moved
    85106
    86107    // get client thread cluster and local pointer
     
    88109    thread_t * th_ptr = GET_PTR( th_xp );
    89110
    90     // get command type and extended pointer on TXT device
    91     uint32_t type = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.type ) );
    92 
    93 #if CONFIG_DEBUG_HAL_TXT
     111    // 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  ) );
     115    xptr_t   error_xp = XPTR( th_cxy , &th_ptr->txt_cmd.error );
     116
     117#if (CONFIG_DEBUG_SYS_READ & 1)
     118if( type == TXT_READ) enter_tty_cmd_read = (uint32_t)hal_get_cycles();
     119#endif
     120
     121#if (CONFIG_DEBUG_SYS_WRITE & 1)
     122if( type == TXT_WRITE) enter_tty_cmd_write = (uint32_t)hal_get_cycles();
     123#endif
     124
     125#if CONFIG_DEBUG_HAL_TXT_RX
    94126uint32_t cycle = (uint32_t)hal_get_cycles();
    95 if (CONFIG_DEBUG_HAL_TXT < cycle )
    96 printk("\n[DBG] %s : thread %x enter for %s / cycle %d\n",
    97 __FUNCTION__ , CURRENT_THREAD , dev_txt_type_str(type) , cycle );
    98 #endif
    99 
    100     if( type == TXT_WRITE )         // block, enable TX_IRQ, and dechedule for a WRITE
    101     {
    102         xptr_t dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) );
    103 
    104         // get TXT device cluster and local pointer
    105         cxy_t     dev_cxy = GET_CXY( dev_xp );
    106         chdev_t * dev_ptr = GET_PTR( dev_xp );
    107 
    108         // get extended pointer on SOCLIB_TTY base segment
    109         xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
    110 
    111         // get SOCLIB_TTY base segment cluster and local pointer
    112         cxy_t      tty_cxy = GET_CXY( tty_xp );
    113         uint32_t * tty_ptr = GET_PTR( tty_xp );
    114 
    115         // get TTY channel index and channel base address
    116         uint32_t   channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) );
    117         uint32_t * base    = tty_ptr + TTY_SPAN * channel;
    118 
    119         // block server thread
    120         thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    121 
    122         // enable relevant TX_IRQ for a WRITE
    123         hal_remote_sw( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 1 );
    124 
    125         // deschedule
    126         sched_yield( "waiting TXT_TX_ISR completion" );
     127if( (CONFIG_DEBUG_HAL_TXT_RX < cycle) && (type == TXT_READ) )
     128printk("\n[DBG] %s : thread %x enter for RX / cycle %d\n",
     129__FUNCTION__ , CURRENT_THREAD , cycle );
     130#endif
     131
     132#if CONFIG_DEBUG_HAL_TXT_TX
     133uint32_t cycle = (uint32_t)hal_get_cycles();
     134if( (CONFIG_DEBUG_HAL_TXT_TX < cycle) && (type == TXT_WRITE) )
     135printk("\n[DBG] %s : thread %x enter for TX / cycle %d\n",
     136__FUNCTION__ , CURRENT_THREAD , cycle );
     137#endif
     138
     139    // get TXT device pointers
     140    xptr_t    dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) );
     141    cxy_t     dev_cxy = GET_CXY( dev_xp );
     142    chdev_t * dev_ptr = GET_PTR( dev_xp );
     143
     144    // get extended pointer on SOCLIB_TTY base segment
     145    xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
     146
     147    // get SOCLIB_TTY base segment cluster and local pointer
     148    cxy_t      tty_cxy = GET_CXY( tty_xp );
     149    uint32_t * tty_ptr = GET_PTR( tty_xp );
     150
     151    // get TTY channel index and channel base address
     152    uint32_t   channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) );
     153    uint32_t * base    = tty_ptr + TTY_SPAN * channel;
     154
     155    ///////////////////////
     156    if( type == TXT_WRITE )         // write bytes to TTY_TX FIFO
     157    {
     158        fifo = &tty_tx_fifo[channel];
     159
     160        done = 0;
     161
     162        while( done < count )
     163        {
     164            if( fifo->sts < TTY_FIFO_DEPTH )   // put one byte to FIFO if TX_FIFO not full
     165            {
     166                // get one byte from command buffer
     167                byte = hal_remote_lb( buf_xp + done );
     168
     169                // write byte to FIFO
     170                fifo->data[fifo->ptw] = byte;
     171
     172                // prevent race
     173                hal_fence();
     174
     175                // update FIFO state
     176                fifo->ptw = (fifo->ptw + 1) % TTY_FIFO_DEPTH;
     177                hal_atomic_add( &fifo->sts , 1 );
     178
     179                // udate number of bytes moved
     180                done++;
     181
     182                // enable TX_IRQ
     183                hal_remote_sw( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 1 );
     184            }
     185            else                                // block & deschedule if TX_FIFO full
     186            {
     187                // block on ISR
     188                thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR );
     189
     190                // deschedule
     191                sched_yield( "TTY_TX_FIFO full" );
     192            }
     193        }
     194
     195        // set error status in command and return
     196        hal_remote_sw( error_xp , 0 );
    127197    }
    128     else if( type == TXT_READ )        // block, and deschedule for a READ
    129     {
    130         // block server thread
    131         thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    132 
    133         // deschedule
    134         sched_yield( "waiting TXT_RX_ISR completion" );
     198    ///////////////////////////
     199    else if( type == TXT_READ )       // read bytes from TTY_RX FIFO   
     200    {
     201        fifo = &tty_rx_fifo[channel];
     202
     203        done = 0;
     204
     205        while( done < count )
     206        {
     207            if( fifo->sts > 0 )               // get byte from FIFO if not empty
     208            {
     209                // get one byte from FIFO
     210                char byte = fifo->data[fifo->ptr];
     211
     212                // update FIFO state
     213                fifo->ptr = (fifo->ptr + 1) % TTY_FIFO_DEPTH;
     214                hal_atomic_add( &fifo->sts , -1 );
     215
     216                // set byte to command buffer
     217                hal_remote_sb( buf_xp + done , byte );
     218
     219                // udate number of bytes
     220                done++;
     221            }
     222            else                             //  deschedule if FIFO empty
     223            {
     224                // block on ISR
     225                thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR );
     226   
     227                // deschedule
     228                sched_yield( "TTY_TX_FIFO_RX empty" );
     229            }
     230        }  // end while
     231
     232        // set error status in command
     233        hal_remote_sw( error_xp , 0 );
    135234    }
    136235    else
     
    139238    }
    140239
    141 #if CONFIG_DEBUG_HAL_TXT
     240#if CONFIG_DEBUG_HAL_TXT_RX
    142241cycle = (uint32_t)hal_get_cycles();
    143 if (CONFIG_DEBUG_HAL_TXT < cycle )
    144 printk("\n[DBG] %s : thread %x exit after %s / cycle %d\n",
    145 __FUNCTION__ , CURRENT_THREAD , dev_txt_type_str( type ) , cycle );
     242if( (CONFIG_DEBUG_HAL_TXT_RX < cycle) && (type == TXT_READ) )
     243printk("\n[DBG] %s : thread %x exit after RX / cycle %d\n",
     244__FUNCTION__ , CURRENT_THREAD , cycle );
     245#endif
     246
     247#if CONFIG_DEBUG_HAL_TXT_TX
     248cycle = (uint32_t)hal_get_cycles();
     249if( (CONFIG_DEBUG_HAL_TXT_TX < cycle) && (type == TXT_WRITE) )
     250printk("\n[DBG] %s : thread %x exit after TX / cycle %d\n",
     251__FUNCTION__ , CURRENT_THREAD , cycle );
    146252#endif
    147253
     
    155261
    156262}  // end soclib_tty_cmd()
     263
     264/////////////////////////////////////////////////////////////////
     265void __attribute__ ((noinline)) soclib_tty_isr( chdev_t * chdev )
     266{
     267    thread_t   * server;       // pointer on TXT chdev server thread
     268    lid_t        server_lid;   // local index of core running the server thread
     269    uint32_t     channel;      // TXT chdev channel
     270    bool_t       is_rx;        // TXT chdev direction
     271    char         byte;         // byte value
     272    xptr_t       owner_xp;     // extended pointer on foreground process in owner cluster
     273    cxy_t        owner_cxy;   
     274    process_t  * owner_ptr;
     275    pid_t        owner_pid;
     276    tty_fifo_t * fifo;         // pointer on TTY_TX or TTY_RX FIFO
     277    cxy_t        tty_cxy;      // soclib_tty cluster
     278    uint32_t *   tty_ptr;      // soclib_tty segment base address
     279    uint32_t   * base;         // soclib_tty channel base address
     280    xptr_t       status_xp;    // extended pointer on TTY_STATUS register
     281    xptr_t       write_xp;     // extended pointer on TTY_WRITE register
     282    xptr_t       read_xp;      // extended pointer on TTY_READ register
     283
     284    // get TXT chdev channel, direction and server thread
     285    channel    = chdev->channel;
     286    is_rx      = chdev->is_rx;
     287    server     = chdev->server;
     288    server_lid = server->core->lid;
     289
     290#if (CONFIG_DEBUG_SYS_READ & 1)
     291if( is_rx ) enter_tty_isr_read = (uint32_t)hal_get_cycles();
     292#endif
     293
     294#if (CONFIG_DEBUG_SYS_WRITE & 1)
     295if( is_rx == 0 ) enter_tty_isr_write = (uint32_t)hal_get_cycles();
     296#endif
     297
     298#if CONFIG_DEBUG_HAL_TXT_RX
     299uint32_t cycle = (uint32_t)hal_get_cycles();
     300if( (CONFIG_DEBUG_HAL_TXT_RX < cycle) && is_rx )
     301printk("\n[DBG] %s : enter for RX / cycle %d\n", __FUNCTION__ , cycle );
     302#endif
     303
     304#if CONFIG_DEBUG_HAL_TXT_TX
     305uint32_t cycle = (uint32_t)hal_get_cycles();
     306if( (CONFIG_DEBUG_HAL_TXT_TX < cycle) && (is_rx == 0) )
     307printk("\n[DBG] %s : enter for TX / cycle %d\n", __FUNCTION__ , cycle );
     308#endif
     309
     310    // get SOCLIB_TTY peripheral cluster and local pointer
     311    tty_cxy = GET_CXY( chdev->base );
     312    tty_ptr = GET_PTR( chdev->base );
     313
     314    // get channel base address
     315    base    = tty_ptr + TTY_SPAN * channel;
     316
     317    // get extended pointer on TTY registers
     318    status_xp = XPTR( tty_cxy , base + TTY_STATUS );
     319    write_xp  = XPTR( tty_cxy , base + TTY_WRITE );
     320    read_xp   = XPTR( tty_cxy , base + TTY_READ );
     321
     322    /////////////////////////// handle RX //////////////////////
     323    if( is_rx )
     324    {
     325        fifo = &tty_rx_fifo[channel];
     326
     327        // try to move bytes until TTY_READ register empty
     328        while( hal_remote_lw( status_xp ) & TTY_STATUS_RX_FULL )   
     329        {
     330            // get one byte from TTY_READ register & acknowledge RX_IRQ
     331            byte = (char)hal_remote_lb( read_xp );
     332
     333            // filter special character ^Z
     334            if( byte == 0x1A )
     335            {
     336                // get pointers on TXT owner process in owner cluster
     337                owner_xp  = process_txt_get_owner( channel );
     338               
     339                // check process exist
     340                assert( (owner_xp != XPTR_NULL) , __FUNCTION__,
     341                "TXT owner process not found\n" );
     342
     343                // get relevant infos on owner process
     344                owner_cxy = GET_CXY( owner_xp );
     345                owner_ptr = GET_PTR( owner_xp );
     346                owner_pid = hal_remote_lw( XPTR( owner_cxy , &owner_ptr->pid ) );
     347
     348                // block owner process only if it is not a KSH
     349                if( process_get_ppid( owner_xp ) > 1 )
     350                {
     351                    // send stop signal to owner process
     352                    process_sigaction( owner_pid , BLOCK_ALL_THREADS );
     353
     354                    // atomically update owner process termination state
     355                    hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
     356                                          PROCESS_TERM_STOP );
     357                    return;
     358                }
     359            }
     360
     361            // filter special character ^C
     362            if( byte == 0x03 )
     363            {
     364                // get pointers on TXT owner process in owner cluster
     365                owner_xp  = process_txt_get_owner( channel );
     366
     367                // check process exist
     368                assert( (owner_xp != XPTR_NULL) , __FUNCTION__,
     369                "TXT owner process not found\n" );
     370
     371                // get relevant infos on TXT owner process
     372                owner_cxy = GET_CXY( owner_xp );
     373                owner_ptr = GET_PTR( owner_xp );
     374                owner_pid = hal_remote_lw( XPTR( owner_cxy , &owner_ptr->pid ) );
     375
     376                // kill TXT owner process only if it is not INIT
     377                if( owner_pid != 1 )
     378                {
     379                    // remove process from TXT list
     380                    process_txt_detach( owner_xp );
     381
     382                    // mark for delete all processes in all clusters, but the main
     383                    process_sigaction( owner_pid , DELETE_ALL_THREADS );
     384               
     385                    // get pointer on target process main thread
     386                    xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] );
     387
     388                    // block main thread
     389                    thread_block( main_xp , THREAD_BLOCKED_GLOBAL );
     390
     391                    // atomically update owner process termination state
     392                    hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
     393                                          PROCESS_TERM_KILL );
     394                    return;
     395                }
     396            }
     397
     398            // write byte in TTY_RX FIFO if not full / discard byte if full
     399            if ( fifo->sts < TTY_FIFO_DEPTH )
     400            {
     401                // store byte into FIFO
     402                fifo->data[fifo->ptw] = (char)byte;
     403
     404                // avoid race
     405                hal_fence();
     406
     407                // update RX_FIFO state
     408                fifo->ptw = (fifo->ptw + 1) % TTY_FIFO_DEPTH;
     409                hal_atomic_add( &fifo->sts , 1 );
     410
     411                // unblock TXT_RX server thread
     412                thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR );
     413
     414                // send IPI to core running server thread
     415                dev_pic_send_ipi( local_cxy , server_lid );
     416            }
     417            else
     418            {
     419                printk("\n[WARNING] %s : TTY_RX_FIFO[%d] full => discard character <%x>\n",
     420                __FUNCTION__, channel, (uint32_t)byte );
     421            }
     422        }  // end while TTY_READ register full
     423
     424    }  // end RX
     425
     426    ///////////////////////  handle TX  /////////////////////////////
     427    else
     428    {
     429        fifo = &tty_tx_fifo[channel];
     430
     431        // try to move bytes until TX_FIFO empty
     432        while( fifo->sts > 0 )
     433        {
     434            // write one byte to TTY_WRITE register if empty / exit while if full
     435            if( (hal_remote_lw( status_xp ) & TTY_STATUS_TX_FULL) == 0 )
     436            {
     437                // get one byte from TX_FIFO
     438                byte = fifo->data[fifo->ptr];
     439
     440                // update TX_FIFO state
     441                fifo->ptr = (fifo->ptr + 1) % TTY_FIFO_DEPTH;
     442                hal_atomic_add( &fifo->sts , -1 );
     443
     444                // write byte to TTY_WRITE register & acknowledge TX_IRQ
     445                hal_remote_sb( write_xp , byte );
     446            }
     447        }
     448
     449        // disable TX_IRQ
     450        hal_remote_sw( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 0 );
     451
     452        // unblock TXT_TX server thread
     453        thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_ISR );
     454
     455        // send IPI to core running server thread
     456        dev_pic_send_ipi( local_cxy , server_lid );
     457    }  // end TX
     458
     459    hal_fence();
     460
     461#if CONFIG_DEBUG_HAL_TXT_RX
     462cycle = (uint32_t)hal_get_cycles();
     463if( (CONFIG_DEBUG_HAL_TXT_RX < cycle) && is_rx )
     464printk("\n[DBG] %s : exit after RX / cycle %d\n", __FUNCTION__, cycle );
     465#endif
     466
     467#if CONFIG_DEBUG_HAL_TXT_TX
     468cycle = (uint32_t)hal_get_cycles();
     469if( (CONFIG_DEBUG_HAL_TXT_TX < cycle) && (is_rx == 0) )
     470printk("\n[DBG] %s : exit after TX / cycle %d\n", __FUNCTION__, cycle );
     471#endif
     472
     473#if (CONFIG_DEBUG_SYS_READ & 1)
     474if( is_rx ) exit_tty_isr_read = (uint32_t)hal_get_cycles();
     475#endif
     476
     477#if (CONFIG_DEBUG_SYS_WRITE & 1)
     478if( is_rx == 0 ) exit_tty_isr_write = (uint32_t)hal_get_cycles();
     479#endif
     480
     481}  // end soclib_tty_isr()
    157482
    158483/////////////////////////////////////////////////////////////
     
    182507    xptr_t status_xp = XPTR( tty_cxy , tty_ptr + TTY_STATUS );
    183508
    184     // loop on characters (busy waiting strategy)
     509    // loop on characters (busy waiting policy)
    185510    for( i = 0 ; i < count ; i++ )
    186511    {
     
    199524
    200525
    201 /////////////////////////////////////////////////////////////////
    202 void __attribute__ ((noinline)) soclib_tty_isr( chdev_t * chdev )
    203 {
    204     uint32_t    type;         // command type
    205     uint32_t    count;        // number of bytes in buffer
    206     xptr_t      buf_xp;       // extended pointer on buffer
    207     xptr_t      error_xp;     // extended pointer on error field in command
    208     xptr_t      status_xp;    // extended pointer on TTY_STATUS register
    209     xptr_t      write_xp;     // extended pointer on TTY_WRITE register
    210     xptr_t      read_xp;      // extended pointer on TTY_READ register
    211     uint32_t    status;       // TTY terminal status
    212     char        byte;         // read byte
    213     xptr_t      client_xp;    // first client thread in waiting queue
    214     cxy_t       client_cxy;   // firts client thread cluster
    215     thread_t  * client_ptr;   // first client thread pointer
    216     pid_t       pid;          // foreground process identifier
    217     xptr_t      owner_xp;     // extended pointer on foreground process in owner cluster
    218     cxy_t       owner_cxy;   
    219     process_t * owner_ptr;
    220     uint32_t    i;
    221 
    222 #if (CONFIG_DEBUG_SYS_READ & 1)
    223 enter_tty_isr_read = (uint32_t)hal_get_cycles();
    224 #endif
    225 
    226 #if (CONFIG_DEBUG_SYS_WRITE & 1)
    227 enter_tty_isr_write = (uint32_t)hal_get_cycles();
    228 #endif
    229 
    230 #if CONFIG_DEBUG_HAL_TXT
    231 uint32_t cycle = (uint32_t)hal_get_cycles();
    232 if (CONFIG_DEBUG_HAL_TXT < cycle)
    233 printk("\n[DBG] %s : enter / cycle %d\n", __FUNCTION__ , cycle );
    234 #endif
    235 
    236     // get extended pointer on chdev queue root
    237     xptr_t root_xp   = XPTR( local_cxy , &chdev->wait_root );
    238 
    239     // get chdev channel
    240     uint32_t channel = chdev->channel;
    241 
    242     // get first command if queue non empty
    243     if( xlist_is_empty( root_xp ) == false )
    244     {
    245         // get extended pointer on first client thread
    246         client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list );
    247 
    248         // get client thread cluster and local pointer
    249         client_cxy = GET_CXY( client_xp );
    250         client_ptr = GET_PTR( client_xp );
    251 
    252         // get command arguments
    253         type     = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.type   ) );
    254         count    = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.count  ) );
    255         buf_xp   = hal_remote_lwd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ) );
    256         error_xp =                 XPTR( client_cxy , &client_ptr->txt_cmd.error  );
    257     }
    258     else
    259     {
    260         type     = 0xFFFFFFFF;
    261 
    262         // these lines to avoid a GCC warning
    263         count      = 0;
    264         buf_xp     = XPTR_NULL;
    265         error_xp   = XPTR_NULL;
    266         client_cxy = 0;
    267         client_ptr = NULL;
    268     }
    269 
    270     // get SOCLIB_TTY peripheral cluster and local pointer
    271     cxy_t      tty_cxy = GET_CXY( chdev->base );
    272     uint32_t * tty_ptr = GET_PTR( chdev->base );
    273 
    274     // get channel base address
    275     uint32_t * base = tty_ptr + TTY_SPAN * chdev->channel;
    276 
    277     // get extended pointer on TTY registers
    278     status_xp = XPTR( tty_cxy , base + TTY_STATUS );
    279     write_xp  = XPTR( tty_cxy , base + TTY_WRITE );
    280     read_xp   = XPTR( tty_cxy , base + TTY_READ );
    281 
    282     // get TTY_STATUS register value
    283     status = hal_remote_lw( status_xp );
    284 
    285     // 1. handle RX if TTY_READ buffer full
    286     if( status & TTY_STATUS_RX_FULL )   
    287     {
    288         // get a byte from TTY_READ / acknowledge RX_IRQ
    289         byte = (char)hal_remote_lb( read_xp );
    290 
    291         // check character value
    292         if( byte == 0x1A )          // ^Z  =>  stop onwner process
    293         {
    294             // get pid of terminal owner process
    295             pid = process_get_txt_owner( channel );
    296 
    297             // get cluster and pointers on owner process descriptor
    298             owner_xp  = cluster_get_owner_process_from_pid( pid );
    299             owner_cxy = GET_CXY( owner_xp );
    300             owner_ptr = GET_PTR( owner_xp );
    301 
    302             // send stop signal to owner process
    303             process_sigaction( pid , BLOCK_ALL_THREADS );
    304                
    305             // atomically update owner process termination state
    306             hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
    307                                   PROCESS_TERM_STOP );
    308             return;
    309         }
    310         else if( byte == 0x03 )     // ^C  => kill owner process
    311         {
    312             // get pid of terminal owner process
    313             pid = process_get_txt_owner( channel );
    314 
    315             // get cluster and pointers on owner process descriptor
    316             owner_xp  = cluster_get_owner_process_from_pid( pid );
    317             owner_cxy = GET_CXY( owner_xp );
    318             owner_ptr = GET_PTR( owner_xp );
    319 
    320             // send kill signal to owner process
    321             process_sigaction( pid , DELETE_ALL_THREADS );
    322                
    323             // atomically update owner process termination state
    324             hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) ,
    325                                   PROCESS_TERM_KILL );
    326             return;
    327         }
    328         else if( type == TXT_READ ) // pending TXT_READ
    329         {
    330             // write character to command buffer
    331             hal_remote_sb( buf_xp , byte );
    332 
    333             // set I/O operation status in command
    334             hal_remote_sw( error_xp , 0 );
    335 
    336             // unblock server thread
    337             thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR );
    338         }
    339     }
    340 
    341     // 3. handle TX if TXT_WRITE
    342     if( type == TXT_WRITE )
    343     {
    344         // loop on characters
    345         for( i = 0 ; i < count ; i++ )
    346         {
    347             // get TTY_STATUS
    348             status = hal_remote_lw( status_xp );
    349 
    350             if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => move one byte
    351             {
    352                 // get one byte from command buffer
    353                 byte = (char)hal_remote_lb( buf_xp + i );
    354 
    355                 // write byte to TTY_WRITE / acknowledge TX_IRQ
    356                 hal_remote_sb( write_xp , byte );
    357             }
    358             else         // TTY_TX full => update command arguments and exit ISR for retry
    359             {
    360                 hal_remote_sw ( XPTR( client_cxy , &client_ptr->txt_cmd.count ), count-i );
    361                 hal_remote_swd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ), buf_xp+i );
    362                 return;
    363             }
    364         }
    365 
    366         // set I/O operation status in command
    367         hal_remote_sw( error_xp , 0 );
    368 
    369         // disable TX_IRQ
    370         hal_remote_sw( XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE ) , 0 );
    371 
    372         // unblock server thread
    373         thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR );
    374     }
    375 
    376     hal_fence();
    377 
    378 #if CONFIG_DEBUG_HAL_TXT
    379 cycle = (uint32_t)hal_get_cycles();
    380 if (CONFIG_DEBUG_HAL_TXT < cycle)
    381 printk("\n[DBG] %s : exit after %s / cycle %d\n",
    382 __FUNCTION__ , dev_txt_type_str( type ) , cycle );
    383 #endif
    384 
    385 #if (CONFIG_DEBUG_SYS_READ & 1)
    386 if( type == TXT_READ) exit_tty_isr_read = (uint32_t)hal_get_cycles();
    387 #endif
    388 
    389 #if (CONFIG_DEBUG_SYS_WRITE & 1)
    390 if( type == TXT_WRITE) exit_tty_isr_write = (uint32_t)hal_get_cycles();
    391 #endif
    392 
    393 }  // end soclib_tty_isr()
    394 
     526
  • trunk/hal/tsar_mips32/drivers/soclib_tty.h

    r435 r436  
    5252#define TTY_STATUS_RX_FULL     1       // TTY_READ_REG full if 1
    5353#define TTY_STATUS_TX_FULL     2       // TTY_WRITE_REG full if 1
     54
     55/****************************************************************************************
     56 * This Rstructure is used by the soclib_tty_isr for the RX channel.
     57 ***************************************************************************************/
     58
     59#define TTY_FIFO_DEPTH  128
     60
     61typedef struct tty_fifo_s     // 32 bytes
     62{
     63    char          data[TTY_FIFO_DEPTH];   // one char per slot
     64    unsigned int  ptr;                    // next free slot index
     65    unsigned int  ptw;                    // next full slot index
     66    unsigned int  sts;                    // number of full slots
     67} tty_fifo_t;
     68 
    5469
    5570/****************************************************************************************
Note: See TracChangeset for help on using the changeset viewer.