Changeset 435 for trunk/hal


Ignore:
Timestamp:
Feb 20, 2018, 5:32:17 PM (6 years ago)
Author:
alain
Message:

Fix a bad bug in scheduler...

Location:
trunk/hal/tsar_mips32
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/tsar_mips32/core/hal_exception.c

    r432 r435  
    3333#include <scheduler.h>
    3434#include <core.h>
    35 #include <signal.h>
    3635#include <syscalls.h>
    3736#include <remote_spinlock.h>
  • trunk/hal/tsar_mips32/core/hal_interrupt.c

    r432 r435  
    3232void hal_do_interrupt()
    3333{
    34 
    35 irq_dmsg("\n[DBG] %s : core[%x,%d] enter at cycle %d\n",
    36 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
    37 
    38     // As ALMOS-MKH does not define a generic interrupt handler,
    39     // we directly access the local TSAR ICU to call the relevant ISR
     34    // ALMOS-MKH does not define a generic interrupt handler.
     35    // we call the specific TSAR IRQ handler to select the relevant ISR
    4036    soclib_pic_irq_handler();
    41 
    42 irq_dmsg("\n[DBG] %s : core[%x,%d] exit at cycle %d\n",
    43 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
    44 
    4537}
  • trunk/hal/tsar_mips32/drivers/soclib_pic.c

    r432 r435  
    130130                           &pti_status );
    131131
    132     irq_dmsg("\n[DBG] %s : core[%x,%d] enter / WTI = %x / HWI = %x / PTI = %x\n",
    133              __FUNCTION__ , local_cxy , core->lid , wti_status , hwi_status , pti_status );
     132#if CONFIG_DEBUG_HAL_IRQS
     133uint32_t cycle = (uint32_t)hal_get_cycles();
     134if (CONFIG_DEBUG_HAL_IRQS < cycle )
     135printk("\n[DBG] %s : core[%x,%d] enter / WTI = %x / HWI = %x / PTI = %x / cycle %d\n",
     136__FUNCTION__ , local_cxy , core->lid , wti_status , hwi_status , pti_status, cycle );
     137#endif
    134138
    135139    // analyse status and handle up to 3 pending IRQ (one WTI, one HWI, one PTI)
     
    143147            assert( (index == core->lid) , __FUNCTION__ , "illegal IPI index" );
    144148
    145             irq_dmsg("\n[DBG] %s : core[%x,%d] received an IPI / cycle %d\n",
    146              __FUNCTION__ , local_cxy , core->lid , hal_time_stamp() );
    147 
     149#if CONFIG_DEBUG_HAL_IRQS
     150if (CONFIG_DEBUG_HAL_IRQS < cycle )
     151printk("\n[DBG] %s : core[%x,%d] received an IPI\n", __FUNCTION__ , local_cxy , core->lid );
     152#endif
    148153            // acknowledge WTI (this require an XCU read)
    149154            uint32_t   ack  = xcu_base[(XCU_WTI_REG << 5) | core->lid];
     
    171176            else                                 // call relevant ISR
    172177            {
    173                 irq_dmsg("\n[DBG] %s : core[%x,%d] received external WTI %d / cycle %d\n",
    174                 __FUNCTION__ , local_cxy , core->lid , index , hal_time_stamp() );
    175 
     178
     179#if CONFIG_DEBUG_HAL_IRQS
     180if (CONFIG_DEBUG_HAL_IRQS < cycle )
     181printk("\n[DBG] %s : core[%x,%d] received external WTI %d\n",
     182__FUNCTION__ , local_cxy , core->lid , index );
     183#endif
    176184                // call ISR
    177185                    src_chdev->isr( src_chdev );
     
    199207        else                    // call relevant ISR
    200208        {
    201             irq_dmsg("\n[DBG] %s : core[%x,%d] received HWI %d / cycle %d\n",
    202             __FUNCTION__ , local_cxy , core->lid , index , hal_time_stamp() );
    203 
     209
     210#if CONFIG_DEBUG_HAL_IRQS
     211if (CONFIG_DEBUG_HAL_IRQS < cycle )
     212printk("\n[DBG] %s : core[%x,%d] received HWI %d\n",
     213__FUNCTION__ , local_cxy , core->lid , index );
     214#endif
    204215            // call ISR
    205216                    src_chdev->isr( src_chdev );
     
    211222        index = pti_status - 1;
    212223
    213         irq_dmsg("\n[DBG] %s : core[%x,%d] received PTI %d / cycle %d\n",
    214         __FUNCTION__ , core->lid , local_cxy , index , hal_time_stamp() );
    215 
    216224        assert( (index == core->lid) , __FUNCTION__ , "unconsistent PTI index\n");
    217225
     226#if CONFIG_DEBUG_HAL_IRQS
     227if (CONFIG_DEBUG_HAL_IRQS < cycle )
     228printk("\n[DBG] %s : core[%x,%d] received PTI %d\n",
     229__FUNCTION__ , core->lid , local_cxy , index );
     230#endif
    218231        // acknowledge PTI (this require a read access to XCU)
    219232        uint32_t   ack  = xcu_base[(XCU_PTI_ACK << 5) | core->lid];
     
    345358                          chdev_t * src_chdev )
    346359{
     360
     361#if CONFIG_DEBUG_HAL_IRQS
     362uint32_t cycle = (uint32_t)hal_get_cycles();
     363if( CONFIG_DEBUG_HAL_IRQS < cycle )
     364printk("\n[DBG] %s : thread %x enter for core[%x,%d] / cycle %d\n",
     365__FUNCTION__ , CURRENT_THREAD , local_cxy , lid , cycle );
     366#endif
     367
    347368    // get extended & local pointers on PIC chdev descriptor
    348369    xptr_t     pic_xp  = chdev_dir.pic;
     
    401422        ((soclib_pic_core_t *)core->pic_extend)->wti_vector[wti_id] = src_chdev;
    402423
    403 pic_dmsg("\n[DBG] %s : %s / channel = %d / rx = %d / hwi_id = %d / wti_id = %d / cluster = %x\n",
     424#if CONFIG_DEBUG_HAL_IRQS
     425if( CONFIG_DEBUG_HAL_IRQS < cycle )
     426printk("\n[DBG] %s : %s / channel = %d / rx = %d / hwi_id = %d / wti_id = %d / cluster = %x\n",
    404427__FUNCTION__ , chdev_func_str( func ) , channel , is_rx , hwi_id , wti_id , local_cxy );
     428#endif
    405429
    406430    }
     
    420444        ((soclib_pic_core_t *)core->pic_extend)->wti_vector[hwi_id] = src_chdev;
    421445
    422 pic_dmsg("\n[DBG] %s : %s / channel = %d / hwi_id = %d / cluster = %x\n",
     446#if CONFIG_DEBUG_HAL_IRQS
     447if( CONFIG_DEBUG_HAL_IRQS < cycle )
     448printk("\n[DBG] %s : %s / channel = %d / hwi_id = %d / cluster = %x\n",
    423449__FUNCTION__ , chdev_func_str( func ) , channel , hwi_id , local_cxy );
     450#endif
    424451
    425452    }
  • trunk/hal/tsar_mips32/drivers/soclib_tty.c

    r432 r435  
    3030#include <hal_special.h>
    3131
    32 #if CONFIG_READ_DEBUG
    33 extern uint32_t  enter_tty_cmd;
    34 extern uint32_t  exit_tty_cmd;
    35 
    36 extern uint32_t  enter_tty_isr;
    37 extern uint32_t  exit_tty_isr;
     32#if (CONFIG_DEBUG_SYS_READ & 1)
     33extern uint32_t  enter_tty_cmd_read;
     34extern uint32_t  exit_tty_cmd_read;
     35
     36extern uint32_t  enter_tty_isr_read;
     37extern uint32_t  exit_tty_isr_read;
     38#endif
     39
     40#if (CONFIG_DEBUG_SYS_WRITE & 1)
     41extern uint32_t  enter_tty_cmd_write;
     42extern uint32_t  exit_tty_cmd_write;
     43
     44extern uint32_t  enter_tty_isr_write;
     45extern uint32_t  exit_tty_isr_write;
    3846#endif
    3947
     
    5361    // get SOCLIB_TTY device cluster and local pointer
    5462    cxy_t      tty_cxy = GET_CXY( tty_xp );
    55     uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );
    56 
    57     // reset TTY_RX_IRQ_ENABLE
     63    uint32_t * tty_ptr = GET_PTR( tty_xp );
     64
     65    // set TTY_RX_IRQ_ENABLE
    5866    reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_RX_IRQ_ENABLE );
    59     hal_remote_sw( reg_xp , 0 );
     67    hal_remote_sw( reg_xp , 1 );
    6068
    6169    // reset TTY_TX_IRQ_ENABLE
     
    6876{
    6977
    70 #if CONFIG_READ_DEBUG
    71 enter_tty_cmd = hal_time_stamp();
    72 #endif
     78#if (CONFIG_DEBUG_SYS_READ & 1)
     79if( type == TXT_READ) enter_tty_cmd_read = (uint32_t)hal_get_cycles();
     80#endif
     81
     82#if (CONFIG_DEBUG_SYS_WRITE & 1)
     83if( type == TXT_WRITE) enter_tty_cmd_write = (uint32_t)hal_get_cycles();
     84#endif
     85
     86    // get client thread cluster and local pointer
     87    cxy_t      th_cxy = GET_CXY( th_xp );
     88    thread_t * th_ptr = GET_PTR( th_xp );
     89
     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 ) );
    7392
    7493#if CONFIG_DEBUG_HAL_TXT
    7594uint32_t cycle = (uint32_t)hal_get_cycles();
    7695if (CONFIG_DEBUG_HAL_TXT < cycle )
    77 printk("\n[DBG] %s : thread %x enter / cycle %d\n",
    78 __FUNCTION__ , CURRENT_THREAD , cycle );
    79 #endif
    80 
    81     // get client thread cluster and local pointer
    82     cxy_t      th_cxy = GET_CXY( th_xp );
    83     thread_t * th_ptr = (thread_t *)GET_PTR( th_xp );
    84 
    85     // get command type and extended pointer on TXT device
    86     uint32_t type   =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.type ) );
    87     xptr_t   dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) );
    88 
    89     assert( (type == TXT_READ) || (type == TXT_WRITE) , __FUNCTION__, "illegal command type");
    90 
    91     // get TXT device cluster and local pointer
    92     cxy_t     dev_cxy = GET_CXY( dev_xp );
    93     chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    94 
    95     // get extended pointer on SOCLIB_TTY base segment
    96     xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
    97 
    98     // get SOCLIB_TTY base segment cluster and local pointer
    99     cxy_t      tty_cxy = GET_CXY( tty_xp );
    100     uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );
    101 
    102     // get TTY channel index and channel base address
    103     uint32_t   channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) );
    104     uint32_t * base    = tty_ptr + TTY_SPAN * channel;
    105 
    106     // compute extended pointer on relevant TTY register
    107     xptr_t reg_xp;
    108     if( type == TXT_READ )  reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE );
    109     else                    reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE );
    110 
    111     // enable relevant IRQ : data transfer will be done by the TTY_RX ISR)
    112     hal_remote_sw( reg_xp , 1 );
     96printk("\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" );
     127    }
     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" );
     135    }
     136    else
     137    {
     138        assert( false , __FUNCTION__ , "illegal TXT command\n" );
     139    }
    113140
    114141#if CONFIG_DEBUG_HAL_TXT
    115142cycle = (uint32_t)hal_get_cycles();
    116143if (CONFIG_DEBUG_HAL_TXT < cycle )
    117 printk("\n[DBG] %s : thread %x deschedule / cycle %d\n",
    118 __FUNCTION__ , CURRENT_THREAD , cycle );
    119 #endif
    120 
    121     // Block and deschedule server thread
    122     thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    123     sched_yield("blocked on ISR");
    124 
    125 #if CONFIG_DEBUG_HAL_TXT
    126 cycle = (uint32_t)hal_get_cycles();
    127 if (CONFIG_DEBUG_HAL_TXT < cycle )
    128 printk("\n[DBG] %s : thread %x resume / cycle %d\n",
    129 __FUNCTION__ , CURRENT_THREAD , cycle );
    130 #endif
    131 
    132 #if CONFIG_READ_DEBUG
    133 exit_tty_cmd = hal_time_stamp();
     144printk("\n[DBG] %s : thread %x exit after %s / cycle %d\n",
     145__FUNCTION__ , CURRENT_THREAD , dev_txt_type_str( type ) , cycle );
     146#endif
     147
     148#if (CONFIG_DEBUG_SYS_READ & 1)
     149if( type == TXT_READ ) exit_tty_cmd_read = (uint32_t)hal_get_cycles();
     150#endif
     151
     152#if (CONFIG_DEBUG_SYS_WRITE & 1)
     153if( type == TXT_WRITE ) exit_tty_cmd_write = (uint32_t)hal_get_cycles();
    134154#endif
    135155
     
    143163    uint32_t   i;
    144164
    145     xptr_t     dev_xp = ((txt_aux_t *)args)->dev_xp;
    146     char     * buffer = ((txt_aux_t *)args)->buffer;
    147     uint32_t   count  = ((txt_aux_t *)args)->count;
     165    xptr_t     dev_xp = ((txt_sync_args_t *)args)->dev_xp;
     166    char     * buffer = ((txt_sync_args_t *)args)->buffer;
     167    uint32_t   count  = ((txt_sync_args_t *)args)->count;
    148168   
    149169    // get TXT0 chdev cluster and local pointer
     
    182202void __attribute__ ((noinline)) soclib_tty_isr( chdev_t * chdev )
    183203{
    184     uint32_t   type;         // command type
    185     uint32_t   count;        // number of bytes in buffer
    186     xptr_t     buf_xp;       // extended pointer on buffer
    187     xptr_t     status_xp;    // extended pointer on TTY_STATUS register
    188     xptr_t     write_xp;     // extended pointer on TTY_WRITE register
    189     xptr_t     read_xp;      // extended pointer on TTY_READ register
    190     uint32_t   status;       // TTY terminal status
    191     char       byte;         // read byte
    192     uint32_t   i;
    193 
    194 #if (CONFIG_READ_DEBUG & 0x1) || (CONFIG_WRITE_DEBUG & 0x1)
    195 enter_tty_isr = hal_time_stamp();
     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)
     223enter_tty_isr_read = (uint32_t)hal_get_cycles();
     224#endif
     225
     226#if (CONFIG_DEBUG_SYS_WRITE & 1)
     227enter_tty_isr_write = (uint32_t)hal_get_cycles();
    196228#endif
    197229
     
    202234#endif
    203235
    204     // get extended pointer on client thread
    205     xptr_t root      = XPTR( local_cxy , &chdev->wait_root );
    206     xptr_t client_xp = XLIST_FIRST_ELEMENT( root , thread_t , wait_list );
    207 
    208     // get client thread cluster and local pointer
    209     cxy_t      client_cxy = GET_CXY( client_xp );
    210     thread_t * client_ptr = (thread_t *)GET_PTR( client_xp );
    211 
    212     // get command arguments
    213     type    = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.type   ) );
    214     count   = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.count  ) );
    215     buf_xp  = hal_remote_lwd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ) );
     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    }
    216269
    217270    // get SOCLIB_TTY peripheral cluster and local pointer
    218271    cxy_t      tty_cxy = GET_CXY( chdev->base );
    219     uint32_t * tty_ptr = (uint32_t *)GET_PTR( chdev->base );
     272    uint32_t * tty_ptr = GET_PTR( chdev->base );
    220273
    221274    // get channel base address
     
    227280    read_xp   = XPTR( tty_cxy , base + TTY_READ );
    228281
    229     if( type == TXT_READ )              // read one single character
    230     {
    231         // get TTY_STATUS
    232         status = hal_remote_lw( status_xp );
    233 
    234         if( status & TTY_STATUS_RX_FULL )   // TTY_RX full => move one byte
    235         {
    236             // get a byte from TTY_READ, and acknowledge RX_IRQ
    237             byte = (char)hal_remote_lb( read_xp );
    238 
    239             // write it to command buffer
     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
    240331            hal_remote_sb( buf_xp , byte );
    241         }
    242         else                               // buffer empty => exit ISR for retry
    243         {
    244             return;
    245         }
    246 
    247         // disable RX_IRQ
    248         xptr_t reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE );
    249         hal_remote_sw( reg_xp , 0 );
    250     }
    251     else   // type == TXT_WRITE           // write all characters in string
     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 )
    252343    {
    253344        // loop on characters
     
    262353                byte = (char)hal_remote_lb( buf_xp + i );
    263354
    264                 // write byte to TTY_WRITE, and acknowledge TX_IRQ
     355                // write byte to TTY_WRITE / acknowledge TX_IRQ
    265356                hal_remote_sb( write_xp , byte );
    266357            }
     
    273364        }
    274365
     366        // set I/O operation status in command
     367        hal_remote_sw( error_xp , 0 );
     368
    275369        // disable TX_IRQ
    276         xptr_t reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE );
    277         hal_remote_sw( reg_xp , 0 );
    278     }
    279 
    280     // The I/O operation completed when we reach this point
    281 
    282     // set I/O operation status in command
    283     hal_remote_sw( XPTR( client_cxy , &client_ptr->txt_cmd.error ) , 0 );
    284 
    285     // unblock server thread
    286     thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR );
    287 
    288     // unblock client thread
    289     // thread_unblock( client_xp , THREAD_BLOCKED_IO );
     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    }
    290375
    291376    hal_fence();
     
    294379cycle = (uint32_t)hal_get_cycles();
    295380if (CONFIG_DEBUG_HAL_TXT < cycle)
    296 {
    297     if( type == TXT_READ)
    298         printk("\n[DBG] %s : exit after RX / cycle %d\n", __FUNCTION__ , cycle );
    299     else
    300         printk("\n[DBG] %s : exit after TX / cycle %d\n", __FUNCTION__ , cycle );
    301 }     
    302 #endif
    303 
    304 #if (CONFIG_READ_DEBUG & 0x1) || (CONFIG_WRITE_DEBUG & 0x1)
    305 exit_tty_isr = hal_time_stamp();
     381printk("\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)
     386if( type == TXT_READ) exit_tty_isr_read = (uint32_t)hal_get_cycles();
     387#endif
     388
     389#if (CONFIG_DEBUG_SYS_WRITE & 1)
     390if( type == TXT_WRITE) exit_tty_isr_write = (uint32_t)hal_get_cycles();
    306391#endif
    307392
    308393}  // end soclib_tty_isr()
    309394
    310 /*
    311 /////////////////////////////////////////////////////////////////
    312 void __attribute__ ((noinline)) soclib_tty_isr( chdev_t * chdev )
    313 {
    314     xptr_t     root_xp;      // extended pointer on command list root
    315     xptr_t     client_xp;    // extended pointer on client thread
    316     cxy_t      client_cxy;   // client thread cluster
    317     thread_t * client_ptr;   // client_thread local pointer
    318     uint32_t   type;         // command type
    319     uint32_t   count;        // number of bytes in buffer
    320     xptr_t     buf_xp;       // extended pointer on buffer
    321     xptr_t     status_xp;    // extended pointer on TTY_STATUS register
    322     xptr_t     write_xp;     // extended pointer on TTY_WRITE register
    323     xptr_t     read_xp;      // extended pointer on TTY_READ register
    324     uint32_t   status;       // TTY terminal status
    325     char       byte;         // read byte
    326     uint32_t   i;
    327 
    328 #if (CONFIG_READ_DEBUG & 0x1) || (CONFIG_WRITE_DEBUG & 0x1)
    329 enter_tty_isr = hal_time_stamp();
    330 #endif
    331 
    332 txt_dmsg("\n[DBG] %s : core[%x,%d] enter / cycle %d\n",
    333 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid , hal_time_stamp() );
    334 
    335     // get SOCLIB_TTY peripheral cluster and local pointer
    336     cxy_t      tty_cxy = GET_CXY( chdev->base );
    337     uint32_t * tty_ptr = (uint32_t *)GET_PTR( chdev->base );
    338 
    339     // get channel base address
    340     uint32_t * base = tty_ptr + TTY_SPAN * chdev->channel;
    341 
    342     // get extended pointer on TTY registers
    343     status_xp = XPTR( tty_cxy , base + TTY_STATUS );
    344     write_xp  = XPTR( tty_cxy , base + TTY_WRITE );
    345     read_xp   = XPTR( tty_cxy , base + TTY_READ );
    346 
    347     // get TTY_STATUS
    348     status = hal_remote_lw( status_xp );
    349 
    350     // get extended pointer on the command list root
    351     root_xp = XPTR( local_cxy , &chdev->wait_root );
    352 
    353     // get extended pointer on client thread
    354     if(xlist_is_empty(root_xp)) client_xp = XLIST_FIRST_ELEMENT(root, thread_t, wait_list);
    355     else                        client_xp = XPTR_NULL;
    356 
    357     if( client_xp )
    358     {
    359         // get client thread cluster and local pointer
    360         client_cxy = GET_CXY( client_xp );
    361         client_ptr = (thread_t *)GET_PTR( client_xp );
    362 
    363         // get command arguments
    364         type    = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.type   ) );
    365         count   = hal_remote_lw ( XPTR( client_cxy , &client_ptr->txt_cmd.count  ) );
    366         buf_xp  = hal_remote_lwd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ) );
    367     }
    368 
    369     ///////////// handle RX if TTY_RX full
    370     if( status & TTY_STATUS_RX_FULL )   
    371     {
    372         // get a byte from TTY_READ, and acknowledge RX_IRQ
    373         byte = (char)hal_remote_lb( read_xp );
    374 
    375         // FIXME The RX_IRQ must be always enabled !!! 
    376         // xptr_t reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE );
    377         // hal_remote_sw( reg_xp , 0 );
    378 
    379         // analyse received character
    380         switch( byte )
    381         {
    382             case CONTROL_C:          // SIGINT to process
    383             case CONTROL_D:
    384             {
    385                 // TODO SIGINT
    386                 return
    387             }
    388             break;
    389             default:                 
    390             {
    391                 if( (type == TXT_READ) && (client_xp != XPTR_NULL) ) 
    392                 {
    393                     // write byte to command buffer
    394                     hal_remote_sb( buf_xp , byte );
    395 
    396                     // set status in command
    397                     hal_remote_sw( XPTR( client_cxy , &client_ptr->txt_cmd.error ) , 0 );
    398 
    399                     hal_fence();
    400 
    401                     // unblock server thread
    402                     thread_unblock( XPTR(local_cxy,chdev->server), THREAD_BLOCKED_DEV_ISR );
    403                 }
    404                 else                    // discard byte
    405                 {
    406                     // TODO WARNING
    407                     return
    408                 }
    409             }
    410         }
    411     } // end RX handling
    412 
    413     //////////////// handle TX if WRITE command pending
    414     if( (type == TXT_WRITE) && (client_xp != XPTR_NULL) )
    415     {
    416         // loop on characters
    417         for( i = 0 ; i < count ; i++ )
    418         {
    419             // get TTY_STATUS
    420             status = hal_remote_lw( status_xp );
    421 
    422             if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => move one byte
    423             {
    424                 // get one byte from command buffer
    425                 byte = (char)hal_remote_lb( buf_xp + i );
    426 
    427                 // write byte to TTY_WRITE, and acknowledge TX_IRQ
    428                 hal_remote_sb( write_xp , byte );
    429             }
    430             else         // TTY_TX full => update command arguments and exit ISR for retry
    431             {
    432                 hal_remote_sw ( XPTR( client_cxy , &client_ptr->txt_cmd.count ), count-i );
    433                 hal_remote_swd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ), buf_xp+i );
    434                 return;
    435             }
    436         }
    437 
    438         // disable TX_IRQ
    439         xptr_t reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE );
    440         hal_remote_sw( reg_xp , 0 );
    441 
    442         // set I/O operation status in command
    443         hal_remote_sw( XPTR( client_cxy , &client_ptr->txt_cmd.error ) , 0 );
    444 
    445         hal_fence();
    446 
    447         // unblock server thread
    448         thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR );
    449 
    450     }  // end TX handling
    451 
    452 txt_dmsg("\n[DBG] %s : core[%x,%d] exit / cycle %d\n",
    453 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
    454 
    455 #if (CONFIG_READ_DEBUG & 0x1) || (CONFIG_WRITE_DEBUG & 0x1)
    456 exit_tty_isr = hal_time_stamp();
    457 #endif
    458 
    459 }  // end soclib_tty_isr()
    460 
    461 */
  • trunk/hal/tsar_mips32/drivers/soclib_tty.h

    r424 r435  
    2828
    2929/****************************************************************************************
    30  * This driver supports the soclib_multi_tty component.
     30 * This driver supports the vci_tty_tsar component.
    3131 * It implements the generic TXT device API:
    3232 * - transfer one single character from TTY to command "buffer" if to_mem is non-zero.
     
    6262
    6363/****************************************************************************************
    64  * This function implements the TXT_READ & TXT_WRITE commands registered in the client
    65  * thread descriptor (in the txt_cmd field), identified by the <xp_thread> argument.
    66  * Depending on the command type, it only unmasks the relevant TTY_RX / TTY_TX IRQ,
     64 * This function implements both the TXT_READ & TXT_WRITE commands registered in the
     65 * client thread descriptor (in the txt_cmd field), even if ALMOS-MKH defines two
     66 * different chdevs (and consequently two diffeerent server threads) for the RX and TX
     67 * directions. The client thread is identified by the <thread_xp> argument.
     68 * Depending on the command type, it unmasks the relevant TTY_RX / TTY_TX IRQ,
    6769 * and blocks the TXT device server thread on the THREAD_BLOCKED_DEV_ISR, as the data
    6870 * transfer is done by the ISR.
     
    8385
    8486/****************************************************************************************
    85  * This ISR is executed to handle both the TTY_TX_IRQ and the TTY_RX_IRQ.
    86  * - the TTY_RX_IRQ is activated as soon as the TTY_STATUS_RX_FULL bit is set in the
    87  *   TTY status register, indicating a character registered in the TTY_READ register.
     87 * This ISR is executed to handle both the TTY_TX_IRQ and the TTY_RX_IRQ, even if
     88 *   The RX_IRQ is activated as soon as the TTY_STATUS_RX_FULL bit is 1 in the
     89 *   TTY_STATUS register, when the TTY_RX_IRQ_ENABLE is non zero, indicating that
     90 *   the TTY_READ buffer is full and can be read.
     91 *   The TX_IRQ is activated as soon as the TTY_STATUS_TX_FULL bit is 0 in the
     92 *   TTY_STATUS register, when the TTY_TX_IRQ_ENABLE is non zero, indicating that
     93 *   the TTY_WRITE buffer is empty, and can be written.
     94 * WARNING : In ALMOS-MKH, the RX_IRQ is always enabled to catch the control signals,
     95 * but the TX_IRQ is dynamically enabled by the TXT_WRITE command, and disabled when
     96 * the command is completed.
    8897 *
    89  *   . if it exist a TXT_READ command registered in the command queue, and thit copies the
     98 * 1) The ISR first read the TTY_STATUS to get the current state of the TTY_READ and
     99 *   the TTY_WRITE buffers.
     100 *
     101 * 2) It try to read the first command registered in the server thread queue associated
     102 *    to the TTY channel
     103 *
     104 * 2) The ISR handles the RX when the TTY_READ buffer is full :
     105 *   . it read the available character from the TTY_READ buffer, and this
     106 *     acknowledges the RX_IRQ.
     107 *   . if it is a control character ( ^C / ^D / ^Z ) it translate it to the proper
     108 *     signal and execute the relevant sigaction for the foreground process.
     109 *   . if it is a normal character, it try to get the first command registered in the
     110 *     server thread queue. If it is a TXT_READ, it returns this character to the
     111 *     command buffer in the client thread.
     112 *
     113 * 3) The ISR handles the TX when the TTY_WRITE buffer is empty and a TXT_WRITE
     114 *   . it try to get it copies the
    90115 *     character to the command buffer, acknowledges the TTY_RX_IRQ, and unblock the
    91116 *     associated server thread.
    92117     
    93  *   . the control characters are directly handled by the txt ^C / ^D /  and the this IRQ ca
    94  *
     118 *   . the control characters ^C / ^D / ^Z  are directly handled by the ISR and
     119 *     translated to the foreground process.
     120
     121 * - the
    95122 the TXT_READ and TXT_WRITE commands.
    96123 * It gets the command arguments from the first client thread in the TXT chdev queue:
Note: See TracChangeset for help on using the changeset viewer.