Ignore:
Timestamp:
Jun 27, 2017, 2:07:55 PM (8 years ago)
Author:
max@…
Message:

empty out the x86 drivers

Location:
trunk/hal/x86_64/drivers
Files:
4 deleted
10 edited

Legend:

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

    r75 r76  
    2828#include <spinlock.h>
    2929
    30 
    31 ///////////////////////////////////////
    3230void soclib_bdv_init( chdev_t * chdev )
    3331{
    34     // get extended pointer on SOCLIB_BDV peripheral base address
    35         xptr_t  bdv_xp = chdev->base;
    3632
    37     // get hardware device cluster and local pointer
    38     cxy_t      bdv_cxy  = GET_CXY( bdv_xp );
    39     uint32_t * bdv_ptr  = (uint32_t *)GET_PTR( bdv_xp );
     33}
    4034
    41     // get block_size and block_count 
    42         uint32_t block_size = hal_remote_lw( XPTR( bdv_cxy , bdv_ptr + BDV_BLOCK_SIZE_REG ) );
    43         uint32_t block_count = hal_remote_lw( XPTR( bdv_cxy , bdv_ptr + BDV_SIZE_REG ) );
    44 
    45     // set IOC device descriptor extension
    46     chdev->ext.ioc.size  = block_size;
    47     chdev->ext.ioc.count = block_count;
    48 
    49 } // end soclib_bdv_init()
    50 
    51 
    52 //////////////////////////////////////////////////////////////
    5335void __attribute__ ((noinline)) soclib_bdv_cmd( xptr_t th_xp )
    5436{
    55     uint32_t   cmd_type;     // IOC_READ / IOC_WRITE / IOC_SYNC_READ
    56     uint32_t   lba;          // command argument
    57     uint32_t   count;        // command argument
    58     xptr_t     buf_xp;       // command argument
    59     xptr_t     dev_xp;       // command argument
    6037
    61     // get client thread cluster and local pointer
    62     cxy_t      th_cxy = GET_CXY( th_xp );
    63     thread_t * th_ptr = (thread_t *)GET_PTR( th_xp );
     38}
    6439
    65     // get command arguments and extended pointer on IOC device
    66     cmd_type =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.type   ) );
    67     lba      =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.lba    ) );
    68     count    =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.count  ) );
    69     buf_xp   = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.ioc.buf_xp ) );
    70     dev_xp   = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.ioc.dev_xp ) );
    71 
    72     // get IOC device cluster and local pointer
    73     cxy_t      dev_cxy = GET_CXY( dev_xp );
    74     chdev_t  * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    75 
    76     // get extended pointer on SOCLIB-BDV peripheral
    77     xptr_t     bdv_xp = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->base ) );
    78 
    79     // get SOCLIB_BDV device cluster and local pointer
    80     cxy_t      bdv_cxy = GET_CXY( bdv_xp );
    81     uint32_t * bdv_ptr = (uint32_t *)GET_PTR( bdv_xp );
    82 
    83     // split buffer address in two 32 bits words
    84     uint32_t   buf_lsb = (uint32_t)(buf_xp);
    85     uint32_t   buf_msb = (uint32_t)(buf_xp>>32);
    86 
    87     // set operation
    88     uint32_t   op;
    89     if( cmd_type == IOC_WRITE ) op = BDV_OP_WRITE;
    90     else                        op = BDV_OP_READ;
    91 
    92     // set SOCLIB_BDV registers to start one I/O operation
    93     hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_IRQ_ENABLE_REG ) , 1       );
    94     hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_BUFFER_REG     ) , buf_lsb );
    95     hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_BUFFER_EXT_REG ) , buf_msb );
    96     hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_LBA_REG        ) , lba     );
    97     hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_COUNT_REG      ) , count   );
    98     hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_OP_REG         ) , op      );
    99 
    100     // waiting policy  depends on the command type
    101 
    102     if( cmd_type == IOC_SYNC_READ )                  // polling policy
    103     {
    104         uint32_t status;
    105         while (1)
    106         {
    107             status = hal_remote_lw( XPTR( bdv_cxy , bdv_ptr + BDV_STATUS_REG ) );
    108 
    109             if( status == BDV_READ_SUCCESS ) // successfully completed
    110             {
    111                 hal_remote_sw( XPTR( th_cxy , &th_ptr->command.ioc.error ) , 0 );
    112                 break;
    113             }
    114             else if( status == BDV_BUSY )   // non completed
    115             {
    116                 continue;
    117             }
    118             else                            // error reported
    119             {
    120                 hal_remote_sw( XPTR( th_cxy , &th_ptr->command.ioc.error ) , 1 );
    121                 break;
    122             }
    123         }
    124     }
    125     else                                            // descheduling + IRQ policy
    126     {
    127         thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    128         sched_yield();
    129     }
    130    
    131 } // end soclib_bdv_cmd()
    132 
    133 
    134 /////////////////////////////////////////////////////////////////
    13540void __attribute__ ((noinline)) soclib_bdv_isr( chdev_t * chdev )
    13641{
    137     // get extended pointer on client thread
    138     xptr_t root = XPTR( local_cxy , &chdev->wait_root );
    139     xptr_t client_xp = XLIST_FIRST_ELEMENT( root , thread_t , wait_list );
    14042
    141     // get extended pointer on server thread
    142     xptr_t server_xp = XPTR( local_cxy , &chdev->server );
     43}
    14344
    144     // get client thread cluster and local pointer
    145     cxy_t      client_cxy = GET_CXY( client_xp );
    146     thread_t * client_ptr = (thread_t *)GET_PTR( client_xp );
    147 
    148     // get SOCLIB_BDV device cluster and local pointer
    149     cxy_t      bdv_cxy  = GET_CXY( chdev->base );
    150     uint32_t * bdv_ptr  = (uint32_t *)GET_PTR( chdev->base );
    151 
    152     // get BDV status register and acknowledge IRQ
    153         uint32_t status = hal_remote_lw( XPTR( bdv_cxy , bdv_ptr + BDV_STATUS_REG ) );   
    154 
    155     // set operation status in command
    156         if((status != BDV_READ_SUCCESS) && (status != BDV_WRITE_SUCCESS))
    157     {
    158         hal_remote_sw( XPTR( client_cxy , &client_ptr->command.ioc.error ) , 1 );
    159     }
    160         else
    161     {
    162         hal_remote_sw( XPTR( client_cxy , &client_ptr->command.ioc.error ) , 0 );
    163     }
    164 
    165     // unblock server thread
    166     thread_unblock( server_xp , THREAD_BLOCKED_DEV_ISR );
    167 
    168     // unblock client thread
    169     thread_unblock( client_xp , THREAD_BLOCKED_IO );
    170 
    171 } // end soclib_bdv_isr()
    172 
    173 
    174 
  • trunk/hal/x86_64/drivers/soclib_cma.c

    r75 r76  
    2727#include <spinlock.h>
    2828
    29 
    30 /////////////////////////////////////
    3129void soclib_nic_init( xptr_t xp_dev )
    3230{
    33     uint32_t    i;
    34     kmem_req_t  req;
    35    
    36     // get NIC device descriptor cluster and local pointer
    37     cxy_t      dev_cxy  = GET_CXY( dev );
    38     device_t * dev_ptr  = (device_t *)GET_PTR( dev );
    39  
    40     // get hardware device base address
    41         xptr_t     base = hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
    4231
    43     // get hardware device cluster and local pointer
    44     cxy_t      nic_cxy  = GET_CXY( base );
    45     uint32_t * nic_ptr  = (uint32_t *)GET_PTR( base );
     32}
    4633
    47     // initialize Soclib NIC global registers
    48     hal_remote_sw( XPTR( nic_cxy , &nic_ptr + NIC_G_BC_ENABLE ) , 0 );
    49     hal_remote_sw( XPTR( nic_cxy , &nic_ptr + NIC_G_ON        ) , 0 );
    50 
    51     // allocate memory for chbuf descriptor (one page)
    52     if( sizeof(nic_chbuf_t) > CONFIG_PPM_PAGE_SIZE )
    53     {
    54         printk("PANIC in %s : chbuf descriptor exceeds one page\n", __FUNCTION__ );
    55         hal_core_sleep;
    56     }
    57 
    58     req->type   = KMEM_PAGE;
    59     req->size   = 0;
    60     req_flags   = AF_KERNEL;
    61 
    62     nic_chbuf_t * chbuf = (nic_chbuf_t *)kmem_alloc( &req );
    63 
    64     if( chbuf == NULL )
    65     {
    66         printk("PANIC in %s : no more memory for chbuf desccriptor\n", __FUNCTION__ );
    67         hal_core_sleep;
    68     }
    69 
    70     // initialise chbuf state
    71     chbuf->cont_id  = 0;
    72     chbuf->pkt_id   = 0;
    73     chbuf->word_id  = 34;
    74    
    75     // allocate containers (one page per container)
    76     // and complete chbuf descriptor initialization
    77     if( CONFIG_PPM_PAGE_SIZE != 4096 )
    78     {
    79         printk("PANIC in %s : chbuf container must be 4 Kbytes\n", __FUNCTION__ );
    80         hal_core_sleep;
    81     }
    82 
    83     for( i = 0 ; i < CONFIG_NIC_CHBUF_DEPTH ; i++ )
    84     {
    85         uint32_t * container = (uint32_t *)kmem_alloc( req );   
    86 
    87         if( container == NULL )
    88         {
    89             printk("PANIC in %s : no more memory for container\n", __FUNCTION__ );
    90             hal_core_sleep;
    91         }
    92        
    93         chbuf->cont[i] = container;
    94         chbuf->full[i] = (paddr_t)XPTR( local_cxy , container );
    95     }
    96 
    97     // get a free WTI mailbox
    98     uint32_t wti_id = dev_icu_wti_alloc();
    99     if( wti_id == -1 )
    100     {
    101         printk("PANIC in %s : cannot allocate WTI mailbox\n", __FUNCTION__ );
    102         hal_core_sleep;
    103     }
    104 
    105     // enable WTI IRQ in local ICU and update WTI interrupt vector
    106     dev_icu_enable_irq( WTI_TYPE , wti_id , xp_dev );
    107 
    108     // link NIC IRQ to WTI mailbox in PIC component
    109     uint32_t irq_id;
    110     if( is_rx ) irq_id = devices_irq.nic_rx[channel];
    111     else        irq_id = devices_irq.nic_tx[channel];
    112     dev_pic_bind_irq( irq_id , local_cxy , wti_id );
    113 
    114 } // end soclib_nic_init()
    115 
    116 
    117 ////////////////////////////////////////////////
    11834void __attribute__ ((noinline)) soclib_nic_cmd()
    11935{
    120     uint32_t       cmd;          // command type   
    121     char         * buffer;       // pointer on command buffer   
    122     uint32_t       length;       // Ethernet packet length
    123     uint32_t       offset;       // offset in buffer
    124     nic_chbuf_t  * chbuf;        // pointer on chbuf descriptor
    125     uint32_t       cont_id;      // index of current container in chbuf
    126     uint32_t       pkt_id;       // index of current packet in container
    127     uint32_t       word_id;      // index of first word of current packet in container
    128     uint32_t     * container;    // pointer on container (array of uint32_t)
    129     uint16_t     * header;       // pointer on container header (array of uint16_t)
    130     uint32_t       npackets;     // number of packets in current container
    13136
    132     volatile uint64_t  sts;  // container descriptor (containing status)
     37}
    13338
    134     thread_t * this = CURRENT_THREAD;
    135 
    136     // get command arguments
    137     cmd    = this->dev.nic.cmd;
    138     buffer = this->dev.nic.buffer;
    139     length = this->dev.nic.length;
    140 
    141     // get chbuf descriptor pointer
    142     chbuf = (nic_chbuf_t *)dev->ext.nic.queue;
    143 
    144     // analyse command type
    145     switch( cmd )
    146     {
    147         /////////////////////////////////////////////////////////////////////////////
    148         case NIC_CMD_READ:   // transfer one packet from RX queue to command buffer
    149         {
    150             // get current container index
    151             cont_id = chbuf->cont_id;
    152            
    153             if( chbuf->full[cont_id] == 0 )  // container empty
    154             {
    155                 printk("PANIC in %s : read an empty container\n", __FUNCTION__ );
    156                 hal_core_sleep();
    157             }
    158 
    159             // get pointer on container and header
    160             container = chbuf->cont[cont_id];
    161             header    = (uint16_t *)header;
    162 
    163             // get  expected packet index and first word index in container
    164             pkt_id  = chbuf->pkt_id;
    165             word_id = chbuf->word_id;
    166 
    167             // get packet length and number of packets from container header
    168             length    = header[pkt_id + 2];
    169             npackets  = header[0];
    170 
    171             if( pkt_id >= npackets )  // packet index too large
    172             {
    173                 printk("PANIC in %s : read a non readable container\n", __FUNCTION__ );
    174                 hal_core_sleep();
    175             }
    176 
    177             // move the packet from container to buffer
    178             memcpy( buffer , container + word_id , length );
    179 
    180             // update current packet index and first word index
    181             chbuf->pkt_id  = pkt_id + 1;
    182             if( length & 0x3 ) chbuf->word_id = word_id + (length>>2) + 1;
    183             else               chbuf->word_id = word_id + (length>>2);
    184         }
    185         break;    // end READ
    186            
    187         //////////////////////////////////////////////////////////////////////////
    188         case NIC_CMD_WRITE:  // move one packet from command buffer to TX queue
    189         {
    190             // get current TX container indexes
    191             cont_id = chbuf->cont_id;
    192             pkt_id  = chbuf->pkt_id;
    193             word_id = chbuf->word_id;
    194 
    195             if( chbuf->full[cont_id] != 0 )  // container full
    196             {
    197                 printk("PANIC in %s : write to a full container\n", __FUNCTION__ );
    198                 hal_core_sleep();
    199             }
    200 
    201             // get pointer on container and header
    202             container = chbuf->cont[cont_id];
    203             header    = (uint16_t *)container;
    204 
    205             if( length > ((1024 - word_id)<<2) )  // packet length too large
    206             {
    207                 printk("PANIC in %s : write to a non writable container\n", __FUNCTION__ );
    208                 hal_core_sleep();
    209             }
    210 
    211             // update packet length in container header
    212             header[pkt_id + 2] = (uint16_t)length;
    213 
    214             // move the packet from buffer to container
    215             memcpy( container + word_id , buffer , length );
    216 
    217             // update current packet index and first word index
    218             chbuf->pkt_id  = pkt_id + 1;
    219             if( length & 0x3 ) chbuf->word_id = word_id + (length>>2) + 1;
    220             else               chbuf->word_id = word_id + (length>>2);
    221         }
    222         break;  // end WRITE
    223 
    224         ////////////////////////////////////////////////////////////////////////////
    225         case NIC_CMD_WRITABLE:  // analyse chbuf status / update status if required
    226         {
    227             // get current container state
    228             cont_id = chbuf->cont_id;
    229             word_id = chbuf->word_id;
    230 
    231             // compute current container writable
    232             bool_t ok = ( chbuf->full[cont_id] == 0 ) &&
    233                         ( length <= ((1024 - word_id)<<2) );
    234 
    235             if( ok )                // current container writable
    236             {
    237                 // return chbuf writable
    238                 this->dev.nic.status = true;
    239             }
    240             else                    // current container not writable
    241             {
    242                 // release current container
    243                 chbuf->full[cont_id] = 1;
    244 
    245                 // check next container
    246                 cont_id = (cont_id + 1) % CONFIG_NIC_CHBUF_DEPTH;
    247 
    248                 if( chbuf->full[cont_id] == 0 ) // next container empty
    249                 {
    250                     // update chbuf status
    251                     chbuf->word_id = 34;
    252                     chbuf->cont_id = cont-id;
    253                     chbuf->pkt_id  = 0;
    254                      
    255                     // return chbuf writable
    256                     this->dev.nic.status = true;
    257                 }
    258                 else                            // next container full     
    259                 {
    260                     // return chbuf non writable
    261                     this->dev.nic.status = false;
    262                 }
    263             }
    264         }
    265         break;  // end WRITABLE
    266 
    267         /////////////////////////////////////////////////////////////////////////////
    268         case NIC_CMD_READABLE:  // analyse chbuf status / update status if required
    269         {
    270             // get current container state
    271             cont_id  = chbuf->cont_id;
    272             pkt_id   = chbuf->pkt_id;
    273             npackets = chbuf->cont[cont_id][0] & 0x0000FFFF;
    274            
    275             // compute current container readable
    276             bool_t ok = ( chbuf->full[cont_id] == 1 ) &&
    277                         ( pkt_id < npackets );
    278 
    279             if( ok )                    // current container readable
    280             {
    281                 // return chbuf readable     
    282                 this->dev.nic.status = true;
    283             }
    284             else                        // current container non readable
    285             {
    286                 // release current container
    287                 chbuf->full[cont_id] = 0;
    288 
    289                 // check next container
    290                 cont_id = (cont_id + 1) % CONFIG_NIC_CHBUF_DEPTH;
    291 
    292                 if( chbuf->full[cont_id] == 1 ) // next container full
    293                 {
    294                     // update chbuf status
    295                     chbuf->word_id = 34;
    296                     chbuf->cont_id = cont-id;
    297                     chbuf->pkt_id  = 0;
    298                      
    299                     // return chbuf readable
    300                     this->dev.nic.status = true;
    301                 }
    302                 else                            // next container empty   
    303                 {
    304                     // return chbuf non readable
    305                     this->dev.nic.status = false;
    306                 }
    307             }
    308    
    309         }
    310         break;  // end READABLE
    311     }
    312 } // end soclib_nic_cmd()
    313 
    314 
    315 ////////////////////////////////////////////////////////////////
    31639void __attribute__ ((noinline)) soclib_nic_isr( device_t * dev )
    31740{
    318     cxy_t local_cxy = LOCAL_CUSTER->cxy;
    31941
    320     // acknowledge WTI IRQ TODO
     42}
    32143
    322     // unblock server thread
    323     thread_t * server = dev->server;
    324     thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_IO );
    325 
    326 } // end soclib_nic_isr()
    327 
    328 
    329 
  • trunk/hal/x86_64/drivers/soclib_dma.c

    r75 r76  
    2828#include <soclib_dma.h>
    2929
    30 ///////////////////////////////////////
    3130void soclib_dma_init( chdev_t * chdev )
    3231{
    33     // get hardware device cluster and local pointer
    34     cxy_t      dma_cxy  = GET_CXY( chdev->base );
    35     uint32_t * dma_ptr  = (uint32_t *)GET_PTR( chdev->base );
    3632
    37     // enable interrupts
    38         hal_remote_sw( XPTR( dma_cxy , dma_ptr + DMA_IRQ_DISABLED ) , 0 );
     33}
    3934
    40 } // soclib_dma_init()
    41 
    42 //////////////////////////////////////////////////////////////////
    4335void __attribute__ ((noinline)) soclib_dma_cmd( xptr_t thread_xp )
    4436{
    45     xptr_t     dev_xp;       // extended pointer on DMA devive
    46     xptr_t     dst_xp;       // extended pointer on destination buffer
    47     xptr_t     src_xp;       // extended pointer on source buffer
    48     uint32_t   size;         // buffer size
    4937
    50     // get client thread cluster and local pointer
    51     cxy_t      thread_cxy = GET_CXY( thread_xp );
    52     thread_t * thread_ptr = (thread_t *)GET_PTR( thread_xp );
     38}
    5339
    54     // get command arguments and extended pointer on DMA device
    55     dev_xp = (xptr_t)hal_remote_lwd( XPTR( thread_cxy , &thread_ptr->command.dma.dev_xp ) );
    56     dst_xp = (xptr_t)hal_remote_lwd( XPTR( thread_cxy , &thread_ptr->command.dma.dst_xp ) );
    57     src_xp = (xptr_t)hal_remote_lwd( XPTR( thread_cxy , &thread_ptr->command.dma.src_xp ) );
    58     size   =         hal_remote_lw ( XPTR( thread_cxy , &thread_ptr->command.dma.size   ) );
    59 
    60     // get DMA device cluster and local pointer
    61     cxy_t     dev_cxy = GET_CXY( dev_xp );
    62     chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    63 
    64     // get extended pointer on SOCLIB-DMA peripheral
    65     xptr_t     dma_xp = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->base ) );
    66 
    67     // get SOCLIB_DMA device cluster and local pointer
    68     cxy_t      dma_cxy = GET_CXY( dma_xp );
    69     uint32_t * dma_ptr = (uint32_t *)GET_PTR( dma_xp );
    70 
    71     // get DMA channel index and channel base address
    72     uint32_t * base = dma_ptr + DMA_SPAN * dev_ptr->channel;
    73 
    74     // split dst and src buffers addresses in two 32 bits words
    75     uint32_t   dst_lsb = (uint32_t)(dst_xp);
    76     uint32_t   dst_msb = (uint32_t)(dst_xp>>32);
    77     uint32_t   src_lsb = (uint32_t)(src_xp);
    78     uint32_t   src_msb = (uint32_t)(src_xp>>32);
    79 
    80     // set SOCLIB_DMA registers to start tranfer operation
    81     hal_remote_sw( XPTR( dma_cxy , base + DMA_SRC     ) , src_lsb );
    82     hal_remote_sw( XPTR( dma_cxy , base + DMA_SRC_EXT ) , src_msb );
    83     hal_remote_sw( XPTR( dma_cxy , base + DMA_DST     ) , dst_lsb );
    84     hal_remote_sw( XPTR( dma_cxy , base + DMA_DST_EXT ) , dst_msb );
    85     hal_remote_sw( XPTR( dma_cxy , base + DMA_LEN     ) , size    );
    86 
    87     // Block and deschedule server thread
    88     thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    89     sched_yield();
    90    
    91 } // soclib_dma_cmd()
    92 
    93 /////////////////////////////////////////////////////////////////
    9440void __attribute__ ((noinline)) soclib_dma_isr( chdev_t * chdev )
    9541{
    96     // get extended pointer on client thread
    97     xptr_t root      = XPTR( local_cxy , &chdev->wait_root );
    98     xptr_t client_xp = XLIST_FIRST_ELEMENT( root , thread_t , wait_list );
    9942
    100     // get extended pointer on server thread
    101     xptr_t server_xp = XPTR( local_cxy , &chdev->server );
     43}
    10244
    103     // get client thread cluster and local pointer
    104     cxy_t      client_cxy = GET_CXY( client_xp );
    105     thread_t * client_ptr = (thread_t *)GET_PTR( client_xp );
    106 
    107     // get SOCLIB_DMA peripheral cluster and local pointer
    108     cxy_t      dma_cxy  = GET_CXY( chdev->base );
    109     uint32_t * dma_ptr  = (uint32_t *)GET_PTR( chdev->base );
    110 
    111     // get DMA channel base address
    112     uint32_t * base = dma_ptr + (DMA_SPAN * chdev->channel);
    113 
    114     // get DMA status register
    115         uint32_t status = hal_remote_lw( XPTR( dma_cxy , base + DMA_LEN ) );   
    116 
    117     // acknowledge IRQ
    118     hal_remote_sw( XPTR( dma_cxy , base + DMA_RESET ) , 0 );
    119 
    120     // set operation status in command
    121         error_t  error = ( status != DMA_SUCCESS );
    122     hal_remote_sw( XPTR( client_cxy , &client_ptr->command.dma.error ) , error );
    123 
    124     // unblock server thread
    125     thread_unblock( server_xp , THREAD_BLOCKED_DEV_ISR );
    126 
    127     // unblock client thread
    128     thread_unblock( client_xp , THREAD_BLOCKED_IO );
    129 
    130 } // soclib_dma_isr()
    131 
    132 
    133 
  • trunk/hal/x86_64/drivers/soclib_hba.c

    r75 r76  
    3030#include <thread.h>
    3131
    32 //////////////////////////////////////////////////////////////////////////////////
    33 //   SOCLIB_HBA specific global variables
    34 //////////////////////////////////////////////////////////////////////////////////
    35        
    36 // command list : up to 32 commands
    37 __attribute__((section(".kdata")))
    38 hba_cmd_desc_t     hba_cmd_list[32] __attribute__((aligned(0x40)));   
    39 
    40 // command tables array : one command table per entry in command list
    41 __attribute__((section(".kdata")))
    42 hba_cmd_table_t    hba_cmd_table[32] __attribute__((aligned(0x40)));
    43 
    44 // extended pointer on the owner thread, for each slot
    45 __attribute__((section(".kdata")))
    46 xptr_t             hba_owner_thread[32];
    47 
    48 // bit vector of active slots
    49 __attribute__((section(".kdata")))
    50 uint32_t           hba_active_slots;
    51 
    52 // spinlock protecting the command slot allocator
    53 __attribute__((section(".kdata")))
    54 spinlock_t         hba_lock;
    55 
    56 ///////////////////////////////////////
    5732void soclib_hba_init( chdev_t * chdev )
    5833{
    59     // get hardware device base address
    60         xptr_t  hba_xp = chdev->base;
    6134
    62     // get hardware device cluster and local pointer
    63     cxy_t      hba_cxy  = GET_CXY( hba_xp );
    64     uint32_t * hba_ptr  = (uint32_t *)GET_PTR( hba_xp );
     35}
    6536
    66     // get block_size and block_count 
    67         uint32_t block_size  = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_BLOCK_SIZE_REG ) );
    68         uint32_t block_count = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_BLOCK_COUNT_REG ) );
    69 
    70     // set device descriptor extension
    71     chdev->ext.ioc.size  = block_size;
    72     chdev->ext.ioc.count = block_count;
    73 
    74     // activate HBA interrupts
    75     hal_remote_sw( XPTR( hba_cxy , hba_ptr + HBA_PXIE_REG ) , 0x1 );
    76 
    77         // reset SOCLIB_HBA driver global variable
    78     hba_active_slots = 0;
    79 
    80 } // end soclib_hba_init()
    81 
    82 
    83 //////////////////////////////////////////////////////////////
    8437void __attribute__ ((noinline)) soclib_hba_cmd( xptr_t th_xp )
    8538{
    8639
    87     uint32_t           cmd_type;     // IOC_READ / IOC_WRITE / IOC_SYNC_READ
    88     uint32_t           lba;          // lba    : command argument
    89     uint32_t           count;        // count  : command argument
    90     xptr_t             buf_xp;       // buffer : command argument
    91     xptr_t             dev_xp;       // device : command argument
     40}
    9241
    93     uint32_t           cmd_id;       // current slot index in command bit_vector
    94     hba_cmd_desc_t   * cmd_desc;     // command descriptor pointer   
    95     hba_cmd_table_t  * cmd_table;    // command table pointer
    96 
    97     bool_t             found;
    98     uint32_t           iter;
    99 
    100     // get client thread cluster and local pointer
    101     cxy_t      th_cxy = GET_CXY( th_xp );
    102     thread_t * th_ptr = (thread_t *)GET_PTR( th_xp );
    103 
    104     // get command arguments and extended pointer on IOC device
    105     cmd_type  =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.type   ) );
    106     lba       =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.lba    ) );
    107     count     =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.count  ) );
    108     buf_xp    = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.ioc.buf_xp ) );
    109     dev_xp    = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.ioc.dev_xp ) );
    110 
    111     // get IOC device cluster and local pointer
    112     cxy_t     dev_cxy = GET_CXY( dev_xp );
    113     chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    114 
    115     // get extended pointer on SOCLIB-HBA peripheral
    116     xptr_t     hba_xp = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->base ) );
    117 
    118     // get SOCLIB_HBA device cluster and local pointer
    119     cxy_t      hba_cxy = GET_CXY( hba_xp );
    120     uint32_t * hba_ptr = (uint32_t *)GET_PTR( hba_xp );
    121 
    122     // try to register the I/O operation in a free slot
    123     // returns if success, deschedule if no slot available
    124     // we do not need a lock to access the slot allocator,
    125     // because the driver is only called by the server thread.
    126     while( 1 )
    127     {
    128         // try to find a free slot in the 32 slots command list
    129         cmd_id = 0;
    130         found  = false;
    131         for ( iter = 0 ; iter < 32 ; iter++ )
    132         {
    133             if( (hba_active_slots & (1<<iter) ) == 0 )
    134             {
    135                 found  = true;
    136                 cmd_id = iter;
    137                 hba_active_slots |= (1<<iter);
    138                 break;
    139             }
    140         }
    141 
    142         if( found )  // slot available in SOCLIB_HBA
    143         {
    144             // compute pointers on command descriptor and command table   
    145             cmd_desc  = &hba_cmd_list[cmd_id];
    146             cmd_table = &hba_cmd_table[cmd_id];
    147 
    148             // set  buffer descriptor in command table
    149             cmd_table->buffer.dba  = (uint32_t)(buf_xp);   
    150             cmd_table->buffer.dbau = (uint32_t)(buf_xp >> 32);
    151             cmd_table->buffer.dbc  = count * 512;
    152 
    153             // initialize command table header
    154             cmd_table->header.lba0 = (char)lba;
    155             cmd_table->header.lba1 = (char)(lba>>8);
    156             cmd_table->header.lba2 = (char)(lba>>16);
    157             cmd_table->header.lba3 = (char)(lba>>24);
    158             cmd_table->header.lba4 = 0;
    159             cmd_table->header.lba5 = 0;
    160 
    161             // initialise command descriptor
    162             cmd_desc->prdtl[0] = 1;
    163             cmd_desc->prdtl[1] = 0;
    164             if( cmd_type == IOC_WRITE ) cmd_desc->flag[0] = 0x40;
    165             else                        cmd_desc->flag[0] = 0x00;     
    166 
    167 #if USE_IOB // software L2/L3 cache coherence
    168 
    169             dev_mmc_sync( cmd_table , sizeof(hba_cmd_table_t) );
    170             dev_mmc_sync( cmd_desc , sizeof(hba_cmd_desc_t) );
    171 
    172 #endif // end software L2/L3 cache coherence
    173 
    174             // set hba_owner_thread[slot]
    175             hba_owner_thread[cmd_id] = th_xp;
    176 
    177             // register slot in bit_vector
    178             hba_active_slots |= 1<<cmd_id;
    179  
    180             // set HBA_PXCI_REG to start transfer
    181             hal_remote_sw( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) , 1<<cmd_id );
    182 
    183             // exit the while
    184             break;
    185         }
    186         else   // no slot available in SOCLIB_HBA
    187         {
    188             if( cmd_type == IOC_SYNC_READ )     // fatal if synchronous access
    189             {
    190                 printk("\n[PANIC] in %s : no slot available for a SYNC_READ\n", __FUNCTION__ );
    191                 hal_core_sleep();
    192             }
    193             else                                // retry if asynchronous access.
    194             {
    195                 sched_yield();
    196             }
    197         }
    198     }  // end while to get a slot
    199 
    200     // waiting policy depends on the command type
    201 
    202     if( cmd_type == IOC_SYNC_READ )                // polling, busy waiting
    203     {
    204         uint32_t  pxis;
    205         uint32_t  pxci;
    206         uint32_t  error;
    207         uint32_t  fault_id;
    208         while(1)
    209         {
    210             pxis     = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) );
    211             pxci     = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) );
    212             error    = (pxis & 0x40000000) >> 30;
    213             fault_id = (pxis & 0x1F000000) >> 24;
    214 
    215             if( (pxci & (1<<cmd_id)) == 0 )  // completed
    216             {
    217                 // release slot
    218                 hba_active_slots &= ~(1<<cmd_id);
    219 
    220                 // set operation status in client thread command
    221                 if( error && (fault_id == cmd_id) )
    222                 {
    223                     hal_remote_sw( XPTR( th_cxy , &th_ptr->command.ioc.error ) , 1 );
    224                 }
    225                 else
    226                 {
    227                     hal_remote_sw( XPTR( th_cxy , &th_ptr->command.ioc.error ) , 0 );
    228                 }
    229 
    230                 // exit while
    231                 break;
    232             }   
    233         }
    234     }
    235     else                                           // descheduling + IRQ
    236     {
    237         thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    238         sched_yield();
    239     }
    240            
    241 } // end soclib_hba_cmd()
    242 
    243 
    244 /////////////////////////////////////////////////////////////////
    24542void __attribute__ ((noinline)) soclib_hba_isr( chdev_t * chdev )
    24643{
    247     // get extended pointer on client thread
    248     xptr_t root      = XPTR( local_cxy , &chdev->wait_root );
    249     xptr_t client_xp = XLIST_FIRST_ELEMENT( root , thread_t , wait_list );
    25044
    251     // get client thread cluster and local pointer
    252     cxy_t      client_cxy = GET_CXY( client_xp );
    253     thread_t * client_ptr = (thread_t *)GET_PTR( client_xp );
     45}
    25446
    255     // get SOCLIB_HBA device cluster and local pointer
    256     cxy_t      hba_cxy  = GET_CXY( chdev->base );
    257     uint32_t * hba_ptr  = (uint32_t *)GET_PTR( chdev->base );
    258 
    259     // get HBA_PXIS_REG and HBA_PXCI_REG current values
    260     uint32_t current_pxis = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) );
    261     uint32_t current_pxci = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) );
    262 
    263     uint32_t  error    = (current_pxis & 0x40000000) >> 30;
    264     uint32_t  fault_id = (current_pxis & 0x1F000000) >> 24;
    265     uint32_t  iter;
    266 
    267     // loop on active commands to signal one or several completed I/O operations
    268     for( iter = 0 ; iter < 32 ; iter++ )
    269     {
    270         if ( ( (hba_active_slots & (1<<iter)) != 0 ) &&  // active command
    271              ( (current_pxci     & (1<<iter)) == 0 ) )   // completed command
    272         {
    273             // release the slot
    274             hba_active_slots &= ~(1<<iter);
    275 
    276             // set operation status in client thread command
    277             if( error && (iter == fault_id ) )
    278             {
    279                 hal_remote_sw( XPTR( client_cxy , &client_ptr->command.ioc.error ) , 1 );
    280             }
    281             else
    282             {
    283                 hal_remote_sw( XPTR( client_cxy , &client_ptr->command.ioc.error ) , 0 );
    284             }
    285 
    286             // unblock client thread
    287             thread_unblock( client_xp , THREAD_BLOCKED_IO );
    288  
    289             ioc_dmsg("INFO in %s : thread %x at cycle %d\n",
    290             __FUNCTION__ , hal_remote_lw( XPTR( client_cxy , &client_ptr->trdid ) ) ,
    291             hal_time_stamp() );
    292         }
    293     }
    294 
    295     // reset HBA_PXIS_REG
    296     hal_remote_sw( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) , 0 );
    297 
    298 } // end soclib_hba_isr()
    299 
    300 
    301 
  • trunk/hal/x86_64/drivers/soclib_iob.c

    r75 r76  
    2727#include <soclib_iob.h>
    2828
    29 ///////////////////////////////////////
    3029void soclib_iob_init( chdev_t * chdev )
    3130{
    32     // desactivate IOMMU
    33     hal_remote_sw( chdev->base + (IOB_IOMMU_ACTIVE<<2) , 0 );
     31
    3432}
    3533
    36 ////////////////////////////////////////////
    3734void soclib_iob_set_active( xptr_t   iob_xp,
    3835                            uint32_t value )
    3936{
    40     // get IOX device cluster and local pointer
    41     cxy_t     iob_cxy = GET_CXY( iob_xp );
    42     chdev_t * iob_ptr = (chdev_t *)GET_PTR( iob_xp );
    4337
    44     // get extended pointer on SOCLIB_IOB base_xp segment
    45     xptr_t base_xp = (xptr_t)hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) );
    46 
    47     // set ACTIVE register
    48     hal_remote_sw( base_xp + (IOB_IOMMU_ACTIVE<<2) , value );
    4938}
    5039
    51 //////////////////////////////////////////
    5240void soclib_iob_set_ptpr( xptr_t   iob_xp,
    5341                          uint32_t value )
    5442{
    55     // get IOX device cluster and local pointer
    56     cxy_t     iob_cxy = GET_CXY( iob_xp );
    57     chdev_t * iob_ptr = (chdev_t *)GET_PTR( iob_xp );
    5843
    59     // get extended pointer on SOCLIB_IOB base_xp segment
    60     xptr_t base_xp = (xptr_t)hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) );
    61 
    62     // set PTPR register
    63     hal_remote_sw( base_xp + (IOB_IOMMU_PTPR<<2) , value );
    6444}
    6545
    66 ///////////////////////////////////////////
    6746void soclib_iob_inval_page( xptr_t  iob_xp,
    6847                            vpn_t   vpn )
    6948{
    70     // get IOX device cluster and local pointer
    71     cxy_t     iob_cxy = GET_CXY( iob_xp );
    72     chdev_t * iob_ptr = (chdev_t *)GET_PTR( iob_xp );
    7349
    74     // get extended pointer on SOCLIB_IOB base_xp segment
    75     xptr_t base_xp = (xptr_t)hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) );
    76 
    77     // invalidate TLB entry
    78     hal_remote_sw( base_xp + (IOB_INVAL_PTE<<2) , vpn );
    7950}
    8051
    81 //////////////////////////////////////////////
    8252uint32_t soclib_iob_get_bvar( xptr_t  iob_xp )
    8353{
    84     // get IOX device cluster and local pointer
    85     cxy_t     iob_cxy = GET_CXY( iob_xp );
    86     chdev_t * iob_ptr = (chdev_t *)GET_PTR( iob_xp );
    87 
    88     // get extended pointer on SOCLIB_IOB base_xp segment
    89     xptr_t base_xp = (xptr_t)hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) );
    90 
    91     // get BVAR register
    92     return hal_remote_lw( base_xp + (IOB_IOMMU_BVAR<<2) );
     54    return 0;
    9355}
    9456
    95 ///////////////////////////////////////////////
    9657uint32_t soclib_iob_get_srcid( xptr_t  iob_xp )
    9758{
    98     // get IOX device cluster and local pointer
    99     cxy_t     iob_cxy = GET_CXY( iob_xp );
    100     chdev_t * iob_ptr = (chdev_t *)GET_PTR( iob_xp );
    101 
    102     // get extended pointer on SOCLIB_IOB base_xp segment
    103     xptr_t base_xp = (xptr_t)hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) );
    104 
    105     // get BVAR register
    106     return hal_remote_lw( base_xp + (IOB_IOMMU_SRCID<<2) );
     59   return 0;
    10760}
    10861
    109 ///////////////////////////////////////////////
    11062uint32_t soclib_iob_get_error( xptr_t  iob_xp )
    11163{
    112     // get IOX device cluster and local pointer
    113     cxy_t     iob_cxy = GET_CXY( iob_xp );
    114     chdev_t * iob_ptr = (chdev_t *)GET_PTR( iob_xp );
    115 
    116     // get extended pointer on SOCLIB_IOB base_xp segment
    117     xptr_t base_xp = (xptr_t)hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) );
    118 
    119     // get BVAR register
    120     return hal_remote_lw( base_xp + (IOB_IOMMU_ERROR<<2) );
     64   return 0;
    12165}
    12266
    123 
    124 // Local Variables:
    125 // tab-width: 4
    126 // c-basic-offset: 4
    127 // c-file-offsets:((innamespace . 0)(inline-open . 0))
    128 // indent-tabs-mode: nil
    129 // End:
    130 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
    131 
  • trunk/hal/x86_64/drivers/soclib_mmc.c

    r75 r76  
    3131#include <printk.h>
    3232
    33 
    34 ///////////////////////////////////////
    3533void soclib_mmc_init( chdev_t * chdev )
    3634{
    37     // get pointer on MMC segment base
    38     uint32_t * base = (uint32_t *)GET_PTR( chdev->base );
    3935
    40     // enable MMC IRQ
    41     *(base + (SOCLIB_MMC_ERROR_FUNC << 7) + SOCLIB_MMC_ERROR_IRQ_ENABLE) = 1;
    4236}
    4337
    44 
    45 //////////////////////////////////////////////////////////////
    4638void __attribute__ ((noinline)) soclib_mmc_cmd( xptr_t th_xp )
    4739{
    48     xptr_t     dev_xp;       // extended pointer on MMC device
    49     uint32_t   type;         // MMC command : type
    50     uint64_t   buf_paddr;    // MMC command : buffer physical address
    51     uint32_t   buf_size;     // MMC command : buffer size
    52     uint32_t   reg_index;    // MMC command : register index in MMC peripheral
    53     uint32_t * reg_ptr;      // MMC command : pointer on dst/src buffer in client cluster
    5440
    55     // get client thread cluster and local pointer
    56     cxy_t      th_cxy = GET_CXY( th_xp );
    57     thread_t * th_ptr = (thread_t *)GET_PTR( th_xp );
     41}
    5842
    59     // get command type and extended pointer on MMC device
    60     type   =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.mmc.type   ) );
    61     dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.mmc.dev_xp ) );
    62 
    63     // get MMC device cluster and local pointer
    64     cxy_t     dev_cxy = GET_CXY( dev_xp );
    65     chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    66 
    67     // get extended pointer on SOCLIB-MMC peripheral
    68     xptr_t     mmc_xp = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->base ) );
    69 
    70     // get SOCLIB_MMC peripheral cluster and local pointer
    71     cxy_t      mmc_cxy = GET_CXY( mmc_xp );
    72     uint32_t * mmc_ptr = (uint32_t *)GET_PTR( mmc_xp );
    73 
    74     if( (type == MMC_CC_INVAL) || (type == MMC_CC_SYNC) )
    75     {
    76         // get buffer paddr
    77         buf_paddr = hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.mmc.buf_paddr ) );
    78 
    79         // split buffer paddr in two 32 bits words
    80         uint32_t   buf_lo = (uint32_t)( buf_paddr );
    81         uint32_t   buf_hi = (uint32_t)( buf_paddr>>32 );
    82 
    83         // get buffer size
    84         buf_size   = hal_remote_lw( XPTR( th_cxy , &th_ptr->command.mmc.buf_size ) );
    85 
    86         // get command type
    87         uint32_t cc_cmd;
    88         if( type == MMC_CC_INVAL )  cc_cmd = SOCLIB_MMC_CC_INVAL;
    89         else                        cc_cmd = SOCLIB_MMC_CC_SYNC;
    90 
    91         // set SOCLIB_MMC registers to start INVAL/SYNC operation
    92         hal_remote_sw( XPTR( mmc_cxy , mmc_ptr + SOCLIB_MMC_ADDR_LO    ) , buf_lo );
    93         hal_remote_sw( XPTR( mmc_cxy , mmc_ptr + SOCLIB_MMC_ADDR_HI    ) , buf_hi );
    94         hal_remote_sw( XPTR( mmc_cxy , mmc_ptr + SOCLIB_MMC_BUF_LENGTH ) , buf_size );
    95         hal_remote_sw( XPTR( mmc_cxy , mmc_ptr + SOCLIB_MMC_CMD_TYPE   ) , cc_cmd );
    96     }
    97     else  // (type == MMC_GET_ERROR) or (type == MMC_GET_ERROR) pr (type == MMC_GET_INSTRU )
    98     {
    99         // get src/dst buffer local pointer and register index
    100         reg_ptr   = (uint32_t *)hal_remote_lpt( XPTR( th_cxy , &th_ptr->command.mmc.reg_ptr ) );
    101         reg_index = hal_remote_lw( XPTR( th_cxy , &th_ptr->command.mmc.reg_index ) );
    102 
    103         // move register to/from local buffer
    104         if( (type == MMC_GET_ERROR) || (type == MMC_GET_INSTRU) )
    105         {
    106             *reg_ptr =  hal_remote_lw( XPTR( mmc_cxy , mmc_ptr + reg_index ) );
    107         }
    108         else  // type == MMC_SET_ERROR
    109         {
    110             hal_remote_sw( XPTR( mmc_cxy , mmc_ptr + reg_index ) , *reg_ptr );
    111         }
    112     }
    113 } // end soclib_mmc_cmd()
    114 
    115 
    116 ////////////////////////////////////////////////////////////////
    11743void __attribute__ ((noinline)) soclib_mmc_isr( chdev_t * chdev )
    11844{
    119     // get pointer on MMC segment base
    120     uint32_t * base = (uint32_t *)GET_PTR( chdev->base );
    12145
    122     // get faulty ADDRESS and SRCID from MMC registers
    123     uint32_t paddr_lo = *(base + (SOCLIB_MMC_ERROR_FUNC << 7) + SOCLIB_MMC_ERROR_ADDR_LO);
    124     uint32_t paddr_hi = *(base + (SOCLIB_MMC_ERROR_FUNC << 7) + SOCLIB_MMC_ERROR_ADDR_HI);
    125     uint32_t srcid    = *(base + (SOCLIB_MMC_ERROR_FUNC << 7) + SOCLIB_MMC_ERROR_SRCID);
     46}
    12647
    127     paddr_t paddr = (((paddr_t)paddr_hi)<<32) + ((paddr_t)paddr_lo);
    128    
    129     // reset MMC IRQ
    130     *(base + (SOCLIB_MMC_ERROR_FUNC << 7) + SOCLIB_MMC_ERROR_IRQ_RESET) = 0;
    131    
    132     // print an error message on kernel terminal TODO : should be improved
    133     printk("\n[ERROR] reported from MMC in cluster %x : faulty address = %l / srcid = %x\n",
    134            paddr , srcid );
    135 
    136 } // end soclib_mmc_isr()
    137 
    138 
    139 
  • trunk/hal/x86_64/drivers/soclib_nic.c

    r75 r76  
    3434#include <soclib_nic.h>
    3535
    36 ///////////////////////////////////////
    3736void soclib_nic_init( chdev_t * chdev )
    3837{
    39     uint32_t    i;
    40     kmem_req_t  req;
    41    
    42     // get hardware device cluster and local pointer
    43     cxy_t      nic_cxy  = GET_CXY( chdev->base );
    44     uint32_t * nic_ptr  = (uint32_t *)GET_PTR( chdev->base );
    4538
    46     // initialize Soclib NIC global registers
    47     hal_remote_sw( XPTR( nic_cxy , &nic_ptr + NIC_G_BC_ENABLE ) , 0 );
    48     hal_remote_sw( XPTR( nic_cxy , &nic_ptr + NIC_G_RUN       ) , 0 );
     39}
    4940
    50     // allocate memory for chbuf descriptor (one page)
    51     assert( (sizeof(nic_chbuf_t) <= CONFIG_PPM_PAGE_SIZE ) , __FUNCTION__ ,
    52             "chbuf descriptor exceeds one page" );
    53 
    54     req.type   = KMEM_PAGE;
    55     req.size   = 0;
    56     req.flags  = AF_KERNEL;
    57 
    58     nic_chbuf_t * chbuf = (nic_chbuf_t *)kmem_alloc( &req );
    59 
    60     assert( (chbuf != NULL) , __FUNCTION__ ,
    61              "cannot allocate chbuf descriptor" );
    62 
    63     // initialise chbuf state
    64     chbuf->cont_id  = 0;
    65     chbuf->pkt_id   = 0;
    66     chbuf->word_id  = 34;
    67    
    68     // allocate containers (one page per container)
    69     // and complete chbuf descriptor initialization
    70     assert( (CONFIG_PPM_PAGE_SIZE == 4096) , __FUNCTION__ ,
    71             "chbuf container must be 4 Kbytes" );
    72 
    73     for( i = 0 ; i < CONFIG_NIC_CHBUF_DEPTH ; i++ )
    74     {
    75         uint32_t * container = (uint32_t *)kmem_alloc( &req );   
    76 
    77         assert( (container != NULL) , __FUNCTION__ ,
    78                 "cannot allocate container" );
    79        
    80         chbuf->cont[i] = container;
    81         chbuf->full[i] = (paddr_t)XPTR( local_cxy , container );
    82     }
    83 } // end soclib_nic_init()
    84 
    85 
    86 //////////////////////////////////////////////////////////////////
    8741void __attribute__ ((noinline)) soclib_nic_cmd( xptr_t thread_xp )
    8842{
    89     uint32_t       cmd;          // command type   
    90     char         * buffer;       // pointer on command buffer   
    91     uint32_t       length;       // Ethernet packet length
    92     xptr_t         dev_xp;       // extended pointer on NIC device
    93     nic_chbuf_t  * chbuf;        // pointer on chbuf descriptor
    94     uint32_t       cont_id;      // index of current container in chbuf
    95     uint32_t       pkt_id;       // index of current packet in container
    96     uint32_t       word_id;      // index of first word of current packet in container
    97     uint32_t     * container;    // pointer on container (array of uint32_t)
    98     uint16_t     * header;       // pointer on container header (array of uint16_t)
    99     uint32_t       npackets;     // number of packets in current container
    10043
    101     // get local pointer for client thread
    102     thread_t * thread_ptr = (thread_t *)GET_PTR( thread_xp );
     44}
    10345
    104     // get command arguments
    105     cmd    = thread_ptr->command.nic.cmd;
    106     buffer = thread_ptr->command.nic.buffer;
    107     length = thread_ptr->command.nic.length;
    108     dev_xp = thread_ptr->command.nic.dev_xp;
    109 
    110     // get local pointer for device
    111     chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    112 
    113     // get chbuf descriptor pointer
    114     chbuf = (nic_chbuf_t *)dev_ptr->ext.nic.queue;
    115 
    116     // analyse command type
    117     switch( cmd )
    118     {
    119         /////////////////////////////////////////////////////////////////////////////
    120         case NIC_CMD_READ:   // transfer one packet from RX queue to command buffer
    121         {
    122             // get current container index
    123             cont_id = chbuf->cont_id;
    124            
    125             if( chbuf->full[cont_id] == 0 )  // container empty
    126             {
    127                 printk("PANIC in %s : read an empty container\n", __FUNCTION__ );
    128                 hal_core_sleep();
    129             }
    130 
    131             // get pointer on container and header
    132             container = chbuf->cont[cont_id];
    133             header    = (uint16_t *)container;
    134 
    135             // get  expected packet index and first word index in container
    136             pkt_id  = chbuf->pkt_id;
    137             word_id = chbuf->word_id;
    138 
    139             // get packet length and number of packets from container header
    140             length    = header[pkt_id + 2];
    141             npackets  = header[0];
    142 
    143             if( pkt_id >= npackets )  // packet index too large
    144             {
    145                 printk("PANIC in %s : read a non readable container\n", __FUNCTION__ );
    146                 hal_core_sleep();
    147             }
    148 
    149             // move the packet from container to buffer
    150             memcpy( buffer , container + word_id , length );
    151 
    152             // update current packet index and first word index
    153             chbuf->pkt_id  = pkt_id + 1;
    154             if( length & 0x3 ) chbuf->word_id = word_id + (length>>2) + 1;
    155             else               chbuf->word_id = word_id + (length>>2);
    156         }
    157         break;    // end READ
    158            
    159         //////////////////////////////////////////////////////////////////////////
    160         case NIC_CMD_WRITE:  // move one packet from command buffer to TX queue
    161         {
    162             // get current TX container indexes
    163             cont_id = chbuf->cont_id;
    164             pkt_id  = chbuf->pkt_id;
    165             word_id = chbuf->word_id;
    166 
    167             if( chbuf->full[cont_id] != 0 )  // container full
    168             {
    169                 printk("PANIC in %s : write to a full container\n", __FUNCTION__ );
    170                 hal_core_sleep();
    171             }
    172 
    173             // get pointer on container and header
    174             container = chbuf->cont[cont_id];
    175             header    = (uint16_t *)container;
    176 
    177             if( length > ((1024 - word_id)<<2) )  // packet length too large
    178             {
    179                 printk("PANIC in %s : write to a non writable container\n", __FUNCTION__ );
    180                 hal_core_sleep();
    181             }
    182 
    183             // update packet length in container header
    184             header[pkt_id + 2] = (uint16_t)length;
    185 
    186             // move the packet from buffer to container
    187             memcpy( container + word_id , buffer , length );
    188 
    189             // update current packet index and first word index
    190             chbuf->pkt_id  = pkt_id + 1;
    191             if( length & 0x3 ) chbuf->word_id = word_id + (length>>2) + 1;
    192             else               chbuf->word_id = word_id + (length>>2);
    193         }
    194         break;  // end WRITE
    195 
    196         ////////////////////////////////////////////////////////////////////////////
    197         case NIC_CMD_WRITABLE:  // analyse chbuf status / update status if required
    198         {
    199             // get current container state
    200             cont_id = chbuf->cont_id;
    201             word_id = chbuf->word_id;
    202 
    203             // compute current container writable
    204             bool_t ok = ( chbuf->full[cont_id] == 0 ) &&
    205                         ( length <= ((1024 - word_id)<<2) );
    206 
    207             if( ok )                // current container writable
    208             {
    209                 // return chbuf writable
    210                 thread_ptr->command.nic.status = true;
    211             }
    212             else                    // current container not writable
    213             {
    214                 // release current container
    215                 chbuf->full[cont_id] = 1;
    216 
    217                 // check next container
    218                 cont_id = (cont_id + 1) % CONFIG_NIC_CHBUF_DEPTH;
    219 
    220                 if( chbuf->full[cont_id] == 0 ) // next container empty
    221                 {
    222                     // update chbuf status
    223                     chbuf->word_id = 34;
    224                     chbuf->cont_id = cont_id;
    225                     chbuf->pkt_id  = 0;
    226                      
    227                     // return chbuf writable
    228                     thread_ptr->command.nic.status = true;
    229                 }
    230                 else                            // next container full     
    231                 {
    232                     // return chbuf non writable
    233                     thread_ptr->command.nic.status = false;
    234                 }
    235             }
    236         }
    237         break;  // end WRITABLE
    238 
    239         /////////////////////////////////////////////////////////////////////////////
    240         case NIC_CMD_READABLE:  // analyse chbuf status / update status if required
    241         {
    242             // get current container state
    243             cont_id  = chbuf->cont_id;
    244             pkt_id   = chbuf->pkt_id;
    245             npackets = chbuf->cont[cont_id][0] & 0x0000FFFF;
    246            
    247             // compute current container readable
    248             bool_t ok = ( chbuf->full[cont_id] == 1 ) &&
    249                         ( pkt_id < npackets );
    250 
    251             if( ok )                    // current container readable
    252             {
    253                 // return chbuf readable     
    254                 thread_ptr->command.nic.status = true;
    255             }
    256             else                        // current container non readable
    257             {
    258                 // release current container
    259                 chbuf->full[cont_id] = 0;
    260 
    261                 // check next container
    262                 cont_id = (cont_id + 1) % CONFIG_NIC_CHBUF_DEPTH;
    263 
    264                 if( chbuf->full[cont_id] == 1 ) // next container full
    265                 {
    266                     // update chbuf status
    267                     chbuf->word_id = 34;
    268                     chbuf->cont_id = cont_id;
    269                     chbuf->pkt_id  = 0;
    270                      
    271                     // return chbuf readable
    272                     thread_ptr->command.nic.status = true;
    273                 }
    274                 else                            // next container empty   
    275                 {
    276                     // return chbuf non readable
    277                     thread_ptr->command.nic.status = false;
    278                 }
    279             }
    280    
    281         }
    282         break;  // end READABLE
    283     }
    284 } // end soclib_nic_cmd()
    285 
    286 
    287 /////////////////////////////////////////////////////////////////
    28846void __attribute__ ((noinline)) soclib_nic_isr( chdev_t * chdev )
    28947{
    290     // get base, size, channel, is_rx from NIC channel device NIC
    291     xptr_t     base    = chdev->base;
    292     uint32_t   channel = chdev->channel;
    293     bool_t     is_rx   = chdev->is_rx;
    29448
    295     // get NIC peripheral cluster and local pointer
    296     cxy_t      cxy_nic = GET_CXY( base );
    297     uint32_t * ptr_nic = (uint32_t *)GET_PTR( base );
     49}
    29850
    299     // compute local pointer on status register
    300     uint32_t * offset;
    301     if( is_rx ) offset = ptr_nic + (NIC_CHANNEL_SPAN * (channel + 1)) + NIC_RX_STATUS;
    302     else        offset = ptr_nic + (NIC_CHANNEL_SPAN * (channel + 1)) + NIC_TX_STATUS;
    303 
    304     // read NIC channel status and acknowledge IRQ
    305     uint32_t status = hal_remote_lw( XPTR( cxy_nic , offset ) );
    306 
    307     if( status != 0 ) hal_core_sleep("%s : illegal address\n", __FUNCTION__ );
    308    
    309     // unblock server thread
    310     thread_t * server = chdev->server;
    311     thread_unblock( XPTR( local_cxy , server ) , THREAD_BLOCKED_IO );
    312 
    313 } // end soclib_nic_isr()
    314 
    315 
    316 
  • trunk/hal/x86_64/drivers/soclib_pic.c

    r75 r76  
    3030#include <vfs.h>
    3131
    32 
    33 ////////////////////////////////////////
    3432void soclib_pic_init( chdev_t  * chdev )
    3533{
    36     // get PIC controller segment cluster and local pointer
    37     cxy_t      seg_cxy = (cxy_t)GET_CXY( chdev->base );
    38     uint32_t * seg_ptr = (uint32_t *)GET_PTR( chdev->base );
    39     uint32_t   i;
    4034
    41     // reset the MASK registers for all input IRQs
    42     for( i = 0 ; i < CONFIG_MAX_IRQS_PER_PIC ; i++ )
    43     {
    44         hal_remote_sw( XPTR( seg_cxy , seg_ptr + i*IOPIC_SPAN + IOPIC_MASK ) , 0 );
    45     }
    4635}
    4736
    48 ////////////////////////////////////////////
    4937void soclib_pic_bind_irq( xptr_t     dev_xp,
    5038                          uint32_t   irq_id,
    5139                          xptr_t     xp_wti )
    5240{
    53     // get PIC device descriptor cluster and local pointer
    54     cxy_t     dev_cxy = GET_CXY( dev_xp );
    55     chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    56  
    57     // get extended pointer on PIC segment base from PIC device descriptor
    58     xptr_t seg_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
    59  
    60     // get PIC controller segment cluster and local pointer
    61     cxy_t      seg_cxy = (cxy_t)GET_CXY( seg_xp);
    62     uint32_t * seg_ptr = (uint32_t *)GET_PTR( seg_xp );
    6341
    64     uint32_t lsb = (uint32_t)xp_wti;
    65     uint32_t msb  = (uint32_t)(xp_wti>>32);
    66 
    67         // set the IOPIC_ADDRESS and IOPIC_EXTEND registers
    68     hal_remote_sw( XPTR( seg_cxy , seg_ptr+irq_id*IOPIC_SPAN+IOPIC_ADDRESS ) , lsb );
    69     hal_remote_sw( XPTR( seg_cxy , seg_ptr+irq_id*IOPIC_SPAN+IOPIC_EXTEND  ) , msb );
    70 
    71     // set IOPIC_MASK register
    72     hal_remote_sw( XPTR( seg_cxy , seg_ptr+irq_id*IOPIC_SPAN+IOPIC_MASK    ) , 1   );
    7342}
    7443
    75 //////////////////////////////////////////////
    7644void soclib_pic_unbind_irq( xptr_t     dev_xp,
    7745                            uint32_t   irq_id )
    7846{
    79     // get PIC device descriptor cluster and local pointer
    80     cxy_t     dev_cxy = GET_CXY( dev_xp );
    81     chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    82  
    83     // get extended pointer on PIC segment base from PIC device descriptor
    84     xptr_t seg_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
    85  
    86     // get PIC controller segment cluster and local pointer
    87     cxy_t      seg_cxy = (cxy_t)GET_CXY( seg_xp);
    88     uint32_t * seg_ptr = (uint32_t *)GET_PTR( seg_xp );
    8947
    90     // set IOPIC_MASK register
    91     hal_remote_sw( XPTR( seg_cxy , seg_ptr+irq_id*IOPIC_SPAN+IOPIC_MASK    ) , 0   );
    9248}
    9349
    94 //////////////////////////////////////////////
    9550void soclib_pic_get_status( xptr_t     dev_xp,
    9651                            uint32_t   irq_id,
    9752                            uint32_t * status)
    9853{
    99     // get PIC device descriptor cluster and local pointer
    100     cxy_t     dev_cxy = GET_CXY( dev_xp );
    101     chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    102  
    103     // get extended pointer on PIC segment base from PIC device descriptor
    104     xptr_t seg_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
    105  
    106     // get PIC controller segment cluster and local pointer
    107     cxy_t      seg_cxy = (cxy_t)GET_CXY( seg_xp);
    108     uint32_t * seg_ptr = (uint32_t *)GET_PTR( seg_xp );
    10954
    110     // return status
    111         *status = hal_remote_lw( XPTR( seg_cxy , seg_ptr+irq_id*IOPIC_SPAN+IOPIC_STATUS ) );
    11255}
    11356
  • trunk/hal/x86_64/drivers/soclib_tty.c

    r75 r76  
    2929#include <hal_special.h>
    3030
    31 ///////////////////////////////////////
    3231void soclib_tty_init( chdev_t * chdev )
    3332{
    34     // get extended pointer on TTY-SOCLIB peripheral base address
    35     xptr_t tty_xp = chdev->base;
    3633
    37     // get SOCLIB_TTY device cluster and local pointer
    38     cxy_t      tty_cxy = GET_CXY( tty_xp );
    39     uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );
    40 
    41     // mask both TTY_RX_IRQ and TTY_TX_IRQ
    42     hal_remote_sw( XPTR( tty_cxy , tty_ptr + TTY_CONFIG_REG ) , 0 );
    4334}
    4435
    45 //////////////////////////////////////////////////////////////
    4636void __attribute__ ((noinline)) soclib_tty_cmd( xptr_t th_xp )
    4737{
    48     // get client thread cluster and local pointer
    49     cxy_t      th_cxy = GET_CXY( th_xp );
    50     thread_t * th_ptr = (thread_t *)GET_PTR( th_xp );
    5138
    52     // get command type and extended pointer on TXT device
    53     uint32_t type   =         hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.txt.type ) );
    54     xptr_t   dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.txt.dev_xp ) );
    55 
    56     // get TXT device cluster and local pointer
    57     cxy_t     dev_cxy = GET_CXY( dev_xp );
    58     chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
    59 
    60     // get extended pointer on SOCLIB_TTY base segment
    61     xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
    62 
    63     // get SOCLIB_TTY base segment cluster and local pointer
    64     cxy_t      tty_cxy = GET_CXY( tty_xp );
    65     uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );
    66 
    67     // get TTY channel index and channel base address
    68     uint32_t   channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) );
    69     uint32_t * base    = tty_ptr + TTY_SPAN * channel;
    70 
    71     if( type == TXT_READ )              // descheduling strategy for calling thread
    72     {
    73         // unmask RX_IRQ (data transfer will be done by the TTY_RX ISR)
    74         xptr_t config_xp = XPTR( tty_cxy , base + TTY_CONFIG_REG );
    75         uint32_t old = hal_remote_lw( config_xp );
    76         uint32_t new = old | TTY_CONFIG_RX_ENABLE;
    77         hal_remote_atomic_cas( config_xp , old , new );
    78 
    79         // Block and deschedule server thread
    80         thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    81         sched_yield();
    82     }
    83     else if( type == TXT_WRITE )        // descheduling strategy for calling thread
    84     {
    85         // unmask TX_IRQ (data transfer will be done by the TTY_TX ISR)
    86         xptr_t config_xp = XPTR( tty_cxy , base + TTY_CONFIG_REG );
    87         uint32_t old = hal_remote_lw( config_xp );
    88         uint32_t new = old | TTY_CONFIG_TX_ENABLE;
    89         hal_remote_atomic_cas( config_xp , old , new );
    90 
    91         // Block and deschedule server thread
    92         thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    93         sched_yield();
    94     }
    95     else if( type == TXT_SYNC_WRITE )  // busy waiting strategy for calling thread
    96     {
    97         uint32_t   status;
    98         bool_t     empty;
    99         uint32_t   i;
    100 
    101         // get source buffer extended pointer & bytes count
    102         uint32_t count  = hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.txt.count ) );
    103         xptr_t   buf_xp = hal_remote_lwd( XPTR( th_cxy , &th_ptr->command.txt.buf_xp ) );
    104 
    105         // loop on characters
    106         for( i = 0 ; i < count ; i++ )
    107         {
    108             do
    109             {
    110                 // get TTY_STATUS_REG
    111                 status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );
    112                 empty  = ( (status & TTY_STATUS_TX_FULL) == 0 );
    113 
    114                 if ( empty )  // TTY_TX empty => transfer one byte
    115                 {
    116                     // get one byte from command buffer in client cluster
    117                     char byte = (char)hal_remote_lb( buf_xp + i );
    118 
    119                     // write byte to TTY_WRITE_REG in TTY cluster
    120                     hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte );
    121                 }
    122             }
    123             while ( empty == false );
    124         }
    125     }
    12639}
    12740
    128 /////////////////////////////////////////////////////////////////
    12941void __attribute__ ((noinline)) soclib_tty_isr( chdev_t * chdev )
    13042{
    131     uint32_t   type;         // command type
    132     uint32_t   count;        // number of bytes in buffer
    133     xptr_t     buf_xp;       // Rextended pointer on buffer
    134     uint32_t   status;       // TTY terminal status
    135     char       byte;         // read byte
    136     uint32_t   i;
    13743
    138     // get extended pointer on client thread
    139     xptr_t root      = XPTR( local_cxy , &chdev->wait_root );
    140     xptr_t client_xp = XLIST_FIRST_ELEMENT( root , thread_t , wait_list );
    141 
    142     // get client thread cluster and local pointer
    143     cxy_t      client_cxy = GET_CXY( client_xp );
    144     thread_t * client_ptr = (thread_t *)GET_PTR( client_xp );
    145 
    146     // get command arguments
    147     type    = hal_remote_lw ( XPTR( client_cxy , &client_ptr->command.txt.type   ) );
    148     count   = hal_remote_lw ( XPTR( client_cxy , &client_ptr->command.txt.count  ) );
    149     buf_xp  = hal_remote_lwd( XPTR( client_cxy , &client_ptr->command.txt.buf_xp ) );
    150 
    151     // get SOCLIB_TTY peripheral cluster and local pointer
    152     cxy_t      tty_cxy = GET_CXY( chdev->base );
    153     uint32_t * tty_ptr = (uint32_t *)GET_PTR( chdev->base );
    154 
    155     // get channel base address
    156     uint32_t * base = tty_ptr + TTY_SPAN * chdev->channel;
    157 
    158     if( type == TXT_READ )              // read one single character
    159     {
    160         // get TTY_STATUS_REG
    161         status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );
    162 
    163         if( status & TTY_STATUS_RX_FULL )   // TTY_RX full => transfer one byte
    164         {
    165             // get a byte from TTY_READ_REG, and acknowledge RX_IRQ
    166             byte = (char)hal_remote_lb( XPTR( tty_cxy , base + TTY_READ_REG ) );
    167 
    168             // write it to command buffer
    169             hal_remote_sb( buf_xp , byte );
    170 
    171             // update TTY_WRITE_REG if echo mode
    172             if( CONFIG_TXT_ECHO_MODE )
    173             {
    174                 if( (byte == '\b') || (byte == 0x7F) )
    175                         {
    176                                 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , '\b' );
    177                                 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , ' '  );
    178                                 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , '\b' );
    179                         }
    180                 else
    181                 {
    182                                 hal_remote_sw( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte );
    183                         }
    184             }
    185         }
    186         else                               // buffer empty => exit ISR for retry
    187         {
    188             return;
    189         }
    190     }
    191     else if( type == TXT_WRITE )         // write a string
    192     {
    193         // loop on characters
    194         for( i = 0 ; i < count ; i++ )
    195         {
    196             // get TTY_STATUS_REG
    197             status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );
    198 
    199             if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => transfer one byte
    200             {
    201                 // get one byte from command buffer
    202                 byte = (char)hal_remote_lb( buf_xp + i );
    203 
    204                 // write byte to TTY_WRITE_REG, and acknowledge TX_IRQ
    205                 hal_remote_sb( XPTR( tty_cxy , base + TTY_STATUS_REG ) , byte );
    206             }
    207             else         // TTY_TX full => update command arguments and exit ISR for retry
    208             {
    209                 hal_remote_sw ( XPTR( client_cxy , &client_ptr->command.txt.count ), count-i );
    210                 hal_remote_swd( XPTR( client_cxy , &client_ptr->command.txt.buf_xp ), buf_xp+i );
    211                 return;
    212             }
    213         }
    214     }
    215 
    216     // The I/O operation completed when we reach this point
    217 
    218     // mask both TTY_RX_IRQ and TTY_TX_IRQ
    219     hal_remote_sw( XPTR( tty_cxy , base + TTY_CONFIG_REG ) , 0 );
    220 
    221     // set I/O operation status in command
    222     hal_remote_sw( XPTR( client_cxy , &client_ptr->command.txt.error ) , 0 );
    223 
    224     // unblock server thread
    225     thread_unblock( XPTR( local_cxy , &chdev->server ) , THREAD_BLOCKED_DEV_ISR );
    226 
    227     // unblock client thread
    228     thread_unblock( client_xp , THREAD_BLOCKED_IO );
    22944}
    23045
  • trunk/hal/x86_64/drivers/soclib_xcu.c

    r75 r76  
    2727#include <chdev.h>
    2828
    29 
    30 
    31 ////////////////////////////////////
    3229void soclib_xcu_init( chdev_t * icu,
    3330                      lid_t     lid )
    3431{
    35     // get local ICU segment base address
    36         uint32_t * base = (uint32_t *)GET_PTR( icu->base );
    3732
    38     // disable all IRQs
    39     base[XCU_MSK_HWI_DISABLE << 5 | lid] = 0xFFFFFFFF;
    40     base[XCU_MSK_WTI_DISABLE << 5 | lid] = 0xFFFFFFFF;
    41     base[XCU_MSK_PTI_DISABLE << 5 | lid] = 0xFFFFFFFF;
    4233}
    4334
    44 ////////////////////////////////////////////
    4535void soclib_xcu_disable_irq( chdev_t  * icu,
    4636                             uint32_t   mask,
     
    4838                             lid_t      lid )
    4939{
    50     // get XCU segment base address
    51         uint32_t * base = (uint32_t *)GET_PTR( icu->base );
    5240
    53     // write into register
    54         if     ( type == WTI_TYPE ) base[XCU_MSK_WTI_DISABLE << 5 | lid] = mask;
    55         else if( type == HWI_TYPE ) base[XCU_MSK_HWI_DISABLE << 5 | lid] = mask;
    56         else                        base[XCU_MSK_PTI_DISABLE << 5 | lid] = mask;
    5741}
    5842
    59 ///////////////////////////////////////////
    6043void soclib_xcu_enable_irq( chdev_t  * icu,
    6144                            uint32_t   mask,
     
    6346                            lid_t      lid )
    6447{
    65     // get XCU segment base address
    66         uint32_t * base = (uint32_t *)GET_PTR( icu->base );
    6748
    68     // write into register
    69         if     ( type == WTI_TYPE ) base[XCU_MSK_WTI_ENABLE << 5 | lid] = mask;
    70         else if( type == HWI_TYPE ) base[XCU_MSK_HWI_ENABLE << 5 | lid] = mask;
    71         else                        base[XCU_MSK_PTI_ENABLE << 5 | lid] = mask;
    7249}
    7350
    74 ///////////////////////////////////////////
    7551void soclib_xcu_get_masks( chdev_t   * icu,
    7652                           lid_t       lid,
     
    7955                           uint32_t  * pti_mask )
    8056{
    81     // get XCU segment base address
    82         uint32_t * base = (uint32_t *)GET_PTR( icu->base );
    83  
    84     // get values from registers
    85     *hwi_mask = base[XCU_MSK_HWI << 5 | lid];
    86     *wti_mask = base[XCU_MSK_WTI << 5 | lid];
    87     *pti_mask = base[XCU_MSK_PTI << 5 | lid];
     57
    8858}
    8959
    90 //////////////////////////////////////////
    9160void soclib_xcu_set_period( chdev_t * icu,
    9261                            uint32_t  index,
    9362                            uint32_t  period )
    9463{
    95     // get local ICU segment base address
    96         uint32_t * base = (uint32_t *)GET_PTR( icu->base );
    9764
    98     // write into register
    99     base[XCU_PTI_PER << 5 | index] = period;
    10065}
    10166
    102 /////////////////////////////////////////////
    10367uint32_t soclib_xcu_ack_timer( chdev_t * icu,
    10468                               uint32_t  index )
    10569{
    106     // get local ICU segment base address
    107         uint32_t * base = (uint32_t *)GET_PTR( icu->base );
    10870
    109     // read from register
    110         return base[XCU_PTI_ACK << 5 | index];
    11171}
    11272
    113 ///////////////////////////////////////////
    11473void soclib_xcu_get_status( chdev_t  * icu,
    11574                            lid_t      lid,
     
    11877                            uint32_t * pti_status )
    11978{
    120     // get local ICU segment base address
    121     uint32_t * base = (uint32_t *)GET_PTR( icu->base );
    12279
    123     // read PRIO register
    124         uint32_t prio = base[XCU_PRIO << 5 | lid];
    125 
    126     *wti_status = (prio & 0x4) ? (((prio >> 24) & 0x1F) + 1) : 0;
    127     *hwi_status = (prio & 0x2) ? (((prio >> 16) & 0x1F) + 1) : 0;
    128     *pti_status = (prio & 0x1) ? (((prio >>  8) & 0x1F) + 1) : 0;
    12980}
    13081
    131 /////////////////////////////////////////
    13282void soclib_xcu_send_ipi( xptr_t  icu_xp,
    13383                          lid_t   lid )
    13484{
    135     // get target ICU device cluster and local pointer
    136     cxy_t       cxy_icu = GET_CXY( icu_xp );
    137     chdev_t  * ptr_icu = (chdev_t *)GET_PTR( icu_xp );
    13885
    139     // get extended pointer on target ICU segment base
    140     xptr_t  xp_base = (xptr_t)hal_remote_lwd( XPTR( cxy_icu , &ptr_icu->base ) );
    141 
    142     // get remote ICU segment local pointer
    143         uint32_t  * base = (uint32_t *)GET_PTR( xp_base );
    144 
    145     // send IPI to remote core
    146         hal_remote_sw( XPTR( cxy_icu , &base[XCU_WTI_REG << 5 | lid] ) , 0 );
    14786}
    14887
    149 //////////////////////////////////////////////
    15088uint32_t * soclib_xcu_wti_ptr( chdev_t  * icu,
    15189                               uint32_t   index )
    15290{
    153     uint32_t * base = (uint32_t *)GET_PTR( icu->base );
    15491
    155     return &base[XCU_WTI_REG << 5 | index];
    15692}
Note: See TracChangeset for help on using the changeset viewer.