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

empty out the x86 drivers

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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 
Note: See TracChangeset for help on using the changeset viewer.