Ignore:
Timestamp:
Mar 18, 2020, 11:16:59 PM (4 years ago)
Author:
alain
Message:

Introduce remote_buf.c/.h & socket.c/.h files.
Update dev_nic.c/.h files.

File:
1 edited

Legend:

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

    r570 r657  
    22 * soclib_dma.c - soclib Multi Channels DMA driver implementation
    33 *
    4  * Author     Alain Greiner (2017)
     4 * Author     Alain Greiner (2017,2018,2019,2020)
    55
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3939    chdev->isr = &soclib_dma_isr;
    4040
    41     // enable interrupts
    42         hal_remote_s32( XPTR( dma_cxy , dma_ptr + DMA_IRQ_DISABLED ) , 0 );
     41    // disable interrupts
     42        hal_remote_s32( XPTR( dma_cxy , dma_ptr + DMA_IRQ_DISABLED ) , 1 );
    4343
    4444} // soclib_dma_init()
     
    4747void __attribute__ ((noinline)) soclib_dma_cmd( xptr_t thread_xp )
    4848{
     49    bool_t     sync;
    4950    xptr_t     dev_xp;       // extended pointer on DMA devive
    5051    xptr_t     dst_xp;       // extended pointer on destination buffer
    5152    xptr_t     src_xp;       // extended pointer on source buffer
    5253    uint32_t   size;         // buffer size
     54    uint32_t   status;       // DMA status
    5355
    5456    // get client thread cluster and local pointer
    55     cxy_t      thread_cxy = GET_CXY( thread_xp );
    56     thread_t * thread_ptr = (thread_t *)GET_PTR( thread_xp );
    57 
    58     // get command arguments and extended pointer on DMA device
    59     dev_xp = (xptr_t)hal_remote_l64( XPTR( thread_cxy , &thread_ptr->dma_cmd.dev_xp ) );
    60     dst_xp = (xptr_t)hal_remote_l64( XPTR( thread_cxy , &thread_ptr->dma_cmd.dst_xp ) );
    61     src_xp = (xptr_t)hal_remote_l64( XPTR( thread_cxy , &thread_ptr->dma_cmd.src_xp ) );
    62     size   =         hal_remote_l32 ( XPTR( thread_cxy , &thread_ptr->dma_cmd.size   ) );
     57    cxy_t      client_cxy = GET_CXY( thread_xp );
     58    thread_t * client_ptr = (thread_t *)GET_PTR( thread_xp );
     59
     60#if (DEBUG_HAL_IOC_RX || DEBUG_HAL_IOC_TX)
     61uint32_t    cycle        = (uint32_t)hal_get_cycles();
     62thread_t  * this         = CURRENT_THREAD;
     63process_t * process      = hal_remote_lpt( XPTR( th_cxy , &th_ptr->process ) );
     64pid_t       client_pid   = hal_remote_l32( XPTR( th_cxy , &process->pid ) );
     65trdid_t     client_trdid = hal_remote_l32( XPTR( th_cxy , &th_ptr->trdid ) );
     66#endif
     67
     68// TODO both the client and the server threads are allways local,
     69// we could replace all these remote accesses by local accesses !!!  [AG]
     70
     71    // get command arguments and extended pointer on DMA device descriptor
     72    sync   =         hal_remote_l32( XPTR( client_cxy , &client_ptr->dma_cmd.sync   ) );
     73    dev_xp = (xptr_t)hal_remote_l64( XPTR( client_cxy , &client_ptr->dma_cmd.dev_xp ) );
     74    dst_xp = (xptr_t)hal_remote_l64( XPTR( client_cxy , &client_ptr->dma_cmd.dst_xp ) );
     75    src_xp = (xptr_t)hal_remote_l64( XPTR( client_cxy , &client_ptr->dma_cmd.src_xp ) );
     76    size   =         hal_remote_l32( XPTR( client_cxy , &client_ptr->dma_cmd.size   ) );
    6377
    6478    // get DMA device cluster and local pointer
     
    6680    chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    6781
    68     // get extended pointer on SOCLIB-DMA peripheral
    69     xptr_t     dma_xp = hal_remote_l32( XPTR( dev_cxy , &dev_ptr->base ) );
    70 
    71     // get SOCLIB_DMA device cluster and local pointer
     82    // get pointers on DMA peripheral
     83    xptr_t     dma_xp  = hal_remote_l32( XPTR( dev_cxy , &dev_ptr->base ) );
    7284    cxy_t      dma_cxy = GET_CXY( dma_xp );
    73     uint32_t * dma_ptr = (uint32_t *)GET_PTR( dma_xp );
     85    uint32_t * dma_ptr = GET_PTR( dma_xp );
    7486
    7587    // get DMA channel index and channel base address
     
    8294    uint32_t   src_msb = (uint32_t)(src_xp>>32);
    8395
    84     // set SOCLIB_DMA registers to start tranfer operation
     96    // set SOCLIB_DMA registers and launch tranfer operation
    8597    hal_remote_s32( XPTR( dma_cxy , base + DMA_SRC     ) , src_lsb );
    8698    hal_remote_s32( XPTR( dma_cxy , base + DMA_SRC_EXT ) , src_msb );
    8799    hal_remote_s32( XPTR( dma_cxy , base + DMA_DST     ) , dst_lsb );
    88100    hal_remote_s32( XPTR( dma_cxy , base + DMA_DST_EXT ) , dst_msb );
    89     hal_remote_s32( XPTR( dma_cxy , base + DMA_LEN     ) , size    );
    90 
    91     // Block and deschedule server thread
    92     thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR );
    93     sched_yield("blocked on ISR");
    94    
     101    hal_remote_s32( XPTR( dma_cxy , base + DMA_LEN_STS ) , size    );
     102
     103 #if DEBUG_HAL_DMA
     104if( DEBUG_HAL_DMA < cycle )
     105printk("\n[%s] thread[%x,%x] launched DMA for client thread[%x,%x] / cycle %d\n",
     106__FUNCTION__, this->process->pid, this->trdid, client_pid, client_trdid, cycle );
     107#endif
     108
     109    // waiting policy  depends on the command type
     110    // - for an asynchronous command, this function is called by the server thread
     111    //   => block and deschedule after launching the transfer.
     112    //   The operation status is reported in the command by the ISR, and the
     113    //   server thread is re-activated by the ISR.
     114    // - for a synchronous command, this function is called by the client thread
     115    //   => mask the DMA_IRQ and poll the DMA status register until transfer completion,
     116    //   and reports status in the command when the transfer is completed.
     117
     118    if( sync )                            // client thread poll status until completion
     119    {
     120        while( 1 )
     121        {
     122            status = hal_remote_l32( XPTR( dma_cxy , base + DMA_LEN_STS ) );
     123
     124            if( (status == DMA_SUCCESS) || (status == DMA_IDLE) )
     125            {
     126                // set operation status in command
     127                hal_remote_s32( XPTR( client_cxy , &client_ptr->dma_cmd.error ) , 0 );
     128
     129#if DEBUG_HAL_DMA
     130cycle = (uint32_t)hal_get_cycles();
     131if( DEBUG_HAL_DMA < cycle )
     132printk("\n[%s] thread[%x,%x] exit after SYNC success / cycle %d\n",
     133__FUNCTION__, this->process->pid, this->trdid, cycle );
     134#endif
     135                // exit while
     136                break;
     137            }
     138            else if( (status == DMA_ERROR_READ) || (status == DMA_ERROR_WRITE) )
     139            {
     140                // set operation status in command
     141                hal_remote_s32( XPTR( client_cxy , &client_ptr->dma_cmd.error ) , 1 );
     142
     143#if DEBUG_HAL_DMA
     144cycle = (uint32_t)hal_get_cycles();
     145if( DEBUG_HAL_DMA < cycle )
     146printk("\n[%s] thread[%x,%x] exit after SYNC failure / cycle %d\n",
     147__FUNCTION__, this->process->pid, this->trdid, cycle );
     148#endif
     149                // exit while
     150                break;
     151            }
     152        }
     153    }   
     154    else                                // server thread block and deschedule
     155    {
     156        // server thread blocks on ISR
     157        thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR );
     158
     159        // enable DMA interrupts
     160            hal_remote_s32( XPTR( dma_cxy , dma_ptr + DMA_IRQ_DISABLED ) , 0 );
     161
     162        // server thread deschedules
     163        sched_yield("blocked on ISR");
     164
     165        // disable DMA interrupts
     166            hal_remote_s32( XPTR( dma_cxy , dma_ptr + DMA_IRQ_DISABLED ) , 1 );
     167
     168#if DEBUG_HAL_DMA
     169cycle = (uint32_t)hal_get_cycles();
     170if( DEBUG_HAL_DMA < cycle )
     171printk("\n[%s] thread[%x,%x] exit after ASYNC / client thread[%x,%x] / cycle %d\n",
     172__FUNCTION__ , this->process->pid, this->trdid, client_pid, client_trdid, cycle );
     173#endif
     174
     175    }
    95176} // soclib_dma_cmd()
    96177
     
    98179void __attribute__ ((noinline)) soclib_dma_isr( chdev_t * chdev )
    99180{
    100     // get extended pointer on client thread
     181    // get extended pointer on server thread
     182    xptr_t server_xp = XPTR( local_cxy , &chdev->server );
     183
     184   // get extended pointer on client thread
    101185    xptr_t root      = XPTR( local_cxy , &chdev->wait_root );
    102186    xptr_t client_xp = XLIST_FIRST( root , thread_t , wait_list );
    103 
    104     // get extended pointer on server thread
    105     xptr_t server_xp = XPTR( local_cxy , &chdev->server );
    106187
    107188    // get client thread cluster and local pointer
     
    113194    uint32_t * dma_ptr  = (uint32_t *)GET_PTR( chdev->base );
    114195
    115     // get DMA channel base address
     196    // build DMA channel base address
    116197    uint32_t * base = dma_ptr + (DMA_SPAN * chdev->channel);
    117198
    118199    // get DMA status register
    119         uint32_t status = hal_remote_l32( XPTR( dma_cxy , base + DMA_LEN ) );   
     200        uint32_t status = hal_remote_l32( XPTR( dma_cxy , base + DMA_LEN_STS ) );   
    120201
    121202    // acknowledge IRQ
     
    129210    thread_unblock( server_xp , THREAD_BLOCKED_ISR );
    130211
    131     // unblock client thread
    132     thread_unblock( client_xp , THREAD_BLOCKED_IO );
    133 
    134212} // soclib_dma_isr()
    135213
Note: See TracChangeset for help on using the changeset viewer.