Ignore:
Timestamp:
Nov 7, 2017, 3:08:12 PM (6 years ago)
Author:
alain
Message:

First implementation of fork/exec.

File:
1 edited

Legend:

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

    r296 r407  
    2727#include <remote_spinlock.h>
    2828#include <thread.h>
     29#include <printk.h>
    2930#include <hal_special.h>
     31
     32#if CONFIG_READ_DEBUG
     33extern uint32_t  enter_tty_cmd;
     34extern uint32_t  exit_tty_cmd;
     35
     36extern uint32_t  enter_tty_isr;
     37extern uint32_t  exit_tty_isr;
     38#endif
    3039
    3140///////////////////////////////////////
    3241void soclib_tty_init( chdev_t * chdev )
    3342{
     43    xptr_t reg_xp;
     44
    3445    chdev->cmd = &soclib_tty_cmd;
    3546    chdev->isr = &soclib_tty_isr;
    36 
    37     // get extended pointer on TTY-SOCLIB peripheral base address
    38     xptr_t tty_xp = chdev->base;
     47    chdev->aux = &soclib_tty_aux;
     48
     49    // get TTY channel and extended pointer on TTY peripheral base address
     50    xptr_t   tty_xp  = chdev->base;
     51    uint32_t channel = chdev->channel;
    3952
    4053    // get SOCLIB_TTY device cluster and local pointer
     
    4255    uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );
    4356
    44     // mask both TTY_RX_IRQ and TTY_TX_IRQ
    45     hal_remote_sw( XPTR( tty_cxy , tty_ptr + TTY_CONFIG_REG ) , 0 );
     57    // reset TTY_RX_IRQ_ENABLE
     58    reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_RX_IRQ_ENABLE );
     59    hal_remote_sw( reg_xp , 0 );
     60
     61    // reset TTY_TX_IRQ_ENABLE
     62    reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_TX_IRQ_ENABLE );
     63    hal_remote_sw( reg_xp , 0 );
    4664}
    4765
     
    4967void __attribute__ ((noinline)) soclib_tty_cmd( xptr_t th_xp )
    5068{
     69
     70#if CONFIG_READ_DEBUG
     71enter_tty_cmd = hal_time_stamp();
     72#endif
     73
     74txt_dmsg("\n[DBG] %s : core[%x,%d] / DEV thread enter / cycle %d\n",
     75__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     76
    5177    // get client thread cluster and local pointer
    5278    cxy_t      th_cxy = GET_CXY( th_xp );
     
    5783    xptr_t   dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) );
    5884
     85    assert( (type == TXT_READ) || (type == TXT_WRITE) , __FUNCTION__, "illegal command type");
     86
    5987    // get TXT device cluster and local pointer
    6088    cxy_t     dev_cxy = GET_CXY( dev_xp );
     
    72100    uint32_t * base    = tty_ptr + TTY_SPAN * channel;
    73101
    74     if( type == TXT_READ )              // descheduling strategy for calling thread
     102    // compute extended pointer on relevant TTY register
     103    xptr_t reg_xp;
     104    if( type == TXT_READ )  reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE );
     105    else                    reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE );
     106
     107    // enable relevant IRQ : data transfer will be done by the TTY_RX ISR)
     108    hal_remote_sw( reg_xp , 1 );
     109
     110txt_dmsg("\n[DBG] %s : core[%x,%d] DEV thread deschedule / cycle %d\n",
     111__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     112
     113    // Block and deschedule server thread
     114    thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
     115    sched_yield();
     116
     117txt_dmsg("\n[DBG] %s : core[%x,%d] / DEV thread resume / cycle %d\n",
     118__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     119
     120#if CONFIG_READ_DEBUG
     121exit_tty_cmd = hal_time_stamp();
     122#endif
     123
     124}  // end soclib_tty_cmd()
     125
     126/////////////////////////////////////////////////////////////
     127void __attribute__ ((noinline)) soclib_tty_aux( void * args )
     128{
     129    uint32_t   status;
     130    bool_t     empty;
     131    uint32_t   i;
     132
     133    xptr_t     dev_xp = ((txt_aux_t *)args)->dev_xp;
     134    char     * buffer = ((txt_aux_t *)args)->buffer;
     135    uint32_t   count  = ((txt_aux_t *)args)->count;
     136   
     137    // get TXT0 chdev cluster and local pointer
     138    cxy_t     dev_cxy = GET_CXY( dev_xp );
     139    chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
     140
     141    // get extended pointer on TTY channel base address
     142    xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
     143
     144    // get TTY channel segment cluster and local pointer
     145    cxy_t      tty_cxy = GET_CXY( tty_xp );
     146    uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );
     147
     148    // get extended pointers on TTY_WRITE & TTY_STATUS registers
     149    xptr_t write_xp  = XPTR( tty_cxy , tty_ptr + TTY_WRITE );
     150    xptr_t status_xp = XPTR( tty_cxy , tty_ptr + TTY_STATUS );
     151
     152    // loop on characters (busy waiting strategy)
     153    for( i = 0 ; i < count ; i++ )
    75154    {
    76         // unmask RX_IRQ (data transfer will be done by the TTY_RX ISR)
    77         xptr_t config_xp = XPTR( tty_cxy , base + TTY_CONFIG_REG );
    78         uint32_t old = hal_remote_lw( config_xp );
    79         uint32_t new = old | TTY_CONFIG_RX_ENABLE;
    80         hal_remote_atomic_cas( config_xp , old , new );
    81 
    82         // Block and deschedule server thread
    83         thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    84         sched_yield( NULL );
     155        do
     156        {
     157            // get TTY_STATUS
     158            status = hal_remote_lw( status_xp );
     159            empty  = ( (status & TTY_STATUS_TX_FULL) == 0 );
     160
     161            // transfer one byte if TX buffer empty
     162            if ( empty )  hal_remote_sb( write_xp , buffer[i] );
     163        }
     164        while ( empty == false );
    85165    }
    86     else if( type == TXT_WRITE )        // descheduling strategy for calling thread
    87     {
    88         // unmask TX_IRQ (data transfer will be done by the TTY_TX ISR)
    89         xptr_t config_xp = XPTR( tty_cxy , base + TTY_CONFIG_REG );
    90         uint32_t old = hal_remote_lw( config_xp );
    91         uint32_t new = old | TTY_CONFIG_TX_ENABLE;
    92         hal_remote_atomic_cas( config_xp , old , new );
    93 
    94         // Block and deschedule server thread
    95         thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    96         sched_yield( NULL );
    97     }
    98     else if( type == TXT_SYNC_WRITE )  // busy waiting strategy for calling thread
    99     {
    100         uint32_t   status;
    101         bool_t     empty;
    102         uint32_t   i;
    103 
    104         // get source buffer extended pointer & bytes count
    105         uint32_t count  = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.count ) );
    106         xptr_t   buf_xp = hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.buf_xp ) );
    107 
    108         // loop on characters
    109         for( i = 0 ; i < count ; i++ )
    110         {
    111             do
    112             {
    113                 // get TTY_STATUS_REG
    114                 status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );
    115                 empty  = ( (status & TTY_STATUS_TX_FULL) == 0 );
    116 
    117                 if ( empty )  // TTY_TX empty => transfer one byte
    118                 {
    119                     // get one byte from command buffer in client cluster
    120                     char byte = (char)hal_remote_lb( buf_xp + i );
    121 
    122                     // write byte to TTY_WRITE_REG in TTY cluster
    123                     hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte );
    124                 }
    125             }
    126             while ( empty == false );
    127         }
    128     }
    129 }  // end soclib_tty_cmd()
     166}  // end soclib_tty_aux()
    130167
    131168
     
    135172    uint32_t   type;         // command type
    136173    uint32_t   count;        // number of bytes in buffer
    137     xptr_t     buf_xp;       // Rextended pointer on buffer
     174    xptr_t     buf_xp;       // extended pointer on buffer
     175    xptr_t     status_xp;    // extended pointer on TTY_STATUS register
     176    xptr_t     write_xp;     // extended pointer on TTY_WRITE register
     177    xptr_t     read_xp;      // extended pointer on TTY_READ register
    138178    uint32_t   status;       // TTY terminal status
    139179    char       byte;         // read byte
    140180    uint32_t   i;
     181
     182#if CONFIG_READ_DEBUG
     183enter_tty_isr = hal_time_stamp();
     184#endif
    141185
    142186    // get extended pointer on client thread
     
    153197    buf_xp  = hal_remote_lwd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ) );
    154198
     199txt_dmsg("\n[DBG] %s : core[%x,%d] enter / cycle %d\n",
     200__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid , hal_time_stamp() );
     201
    155202    // get SOCLIB_TTY peripheral cluster and local pointer
    156203    cxy_t      tty_cxy = GET_CXY( chdev->base );
     
    160207    uint32_t * base = tty_ptr + TTY_SPAN * chdev->channel;
    161208
     209    // get extended pointer on TTY registers
     210    status_xp = XPTR( tty_cxy , base + TTY_STATUS );
     211    write_xp  = XPTR( tty_cxy , base + TTY_WRITE );
     212    read_xp   = XPTR( tty_cxy , base + TTY_READ );
     213
    162214    if( type == TXT_READ )              // read one single character
    163215    {
    164         // get TTY_STATUS_REG
    165         status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );
    166 
    167         if( status & TTY_STATUS_RX_FULL )   // TTY_RX full => transfer one byte
    168         {
    169             // get a byte from TTY_READ_REG, and acknowledge RX_IRQ
    170             byte = (char)hal_remote_lb( XPTR( tty_cxy , base + TTY_READ_REG ) );
     216        // get TTY_STATUS
     217        status = hal_remote_lw( status_xp );
     218
     219        if( status & TTY_STATUS_RX_FULL )   // TTY_RX full => move one byte
     220        {
     221            // get a byte from TTY_READ, and acknowledge RX_IRQ
     222            byte = (char)hal_remote_lb( read_xp );
    171223
    172224            // write it to command buffer
    173225            hal_remote_sb( buf_xp , byte );
    174 
    175             // update TTY_WRITE_REG if echo mode
    176             if( CONFIG_TXT_ECHO_MODE )
    177             {
    178                 if( (byte == '\b') || (byte == 0x7F) )
    179                         {
    180                                 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , '\b' );
    181                                 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , ' '  );
    182                                 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , '\b' );
    183                         }
    184                 else
    185                 {
    186                                 hal_remote_sw( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte );
    187                         }
    188             }
    189226        }
    190227        else                               // buffer empty => exit ISR for retry
     
    192229            return;
    193230        }
     231
     232        // disable RX_IRQ
     233        xptr_t reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE );
     234        hal_remote_sw( reg_xp , 0 );
    194235    }
    195     else if( type == TXT_WRITE )         // write a string
     236    else if( type == TXT_WRITE )         // write all characters in string
    196237    {
    197238        // loop on characters
    198239        for( i = 0 ; i < count ; i++ )
    199240        {
    200             // get TTY_STATUS_REG
    201             status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );
    202 
    203             if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => transfer one byte
     241            // get TTY_STATUS
     242            status = hal_remote_lw( status_xp );
     243
     244            if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => move one byte
    204245            {
    205246                // get one byte from command buffer
    206247                byte = (char)hal_remote_lb( buf_xp + i );
    207248
    208                 // write byte to TTY_WRITE_REG, and acknowledge TX_IRQ
    209                 hal_remote_sb( XPTR( tty_cxy , base + TTY_STATUS_REG ) , byte );
     249                // write byte to TTY_WRITE, and acknowledge TX_IRQ
     250                hal_remote_sb( write_xp , byte );
    210251            }
    211252            else         // TTY_TX full => update command arguments and exit ISR for retry
     
    216257            }
    217258        }
     259
     260        // disable TX_IRQ
     261        xptr_t reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE );
     262        hal_remote_sw( reg_xp , 0 );
    218263    }
    219264
    220265    // The I/O operation completed when we reach this point
    221 
    222     // mask both TTY_RX_IRQ and TTY_TX_IRQ
    223     hal_remote_sw( XPTR( tty_cxy , base + TTY_CONFIG_REG ) , 0 );
    224266
    225267    // set I/O operation status in command
     
    227269
    228270    // unblock server thread
    229     thread_unblock( XPTR( local_cxy , &chdev->server ) , THREAD_BLOCKED_DEV_ISR );
     271    thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR );
    230272
    231273    // unblock client thread
    232274    thread_unblock( client_xp , THREAD_BLOCKED_IO );
    233275
     276    hal_fence();
     277
     278txt_dmsg("\n[DBG] %s : core[%x,%d] exit / cycle %d\n",
     279__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     280
     281#if CONFIG_READ_DEBUG
     282exit_tty_isr = hal_time_stamp();
     283#endif
     284
    234285}  // end soclib_tty_isr()
    235286
Note: See TracChangeset for help on using the changeset viewer.