Changeset 76 for trunk/hal/x86_64/drivers/soclib_bdv.c
- Timestamp:
- Jun 27, 2017, 2:07:55 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/x86_64/drivers/soclib_bdv.c
r75 r76 28 28 #include <spinlock.h> 29 29 30 31 ///////////////////////////////////////32 30 void soclib_bdv_init( chdev_t * chdev ) 33 31 { 34 // get extended pointer on SOCLIB_BDV peripheral base address35 xptr_t bdv_xp = chdev->base;36 32 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 } 40 34 41 // get block_size and block_count42 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 extension46 chdev->ext.ioc.size = block_size;47 chdev->ext.ioc.count = block_count;48 49 } // end soclib_bdv_init()50 51 52 //////////////////////////////////////////////////////////////53 35 void __attribute__ ((noinline)) soclib_bdv_cmd( xptr_t th_xp ) 54 36 { 55 uint32_t cmd_type; // IOC_READ / IOC_WRITE / IOC_SYNC_READ56 uint32_t lba; // command argument57 uint32_t count; // command argument58 xptr_t buf_xp; // command argument59 xptr_t dev_xp; // command argument60 37 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 } 64 39 65 // get command arguments and extended pointer on IOC device66 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 pointer73 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 peripheral77 xptr_t bdv_xp = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->base ) );78 79 // get SOCLIB_BDV device cluster and local pointer80 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 words84 uint32_t buf_lsb = (uint32_t)(buf_xp);85 uint32_t buf_msb = (uint32_t)(buf_xp>>32);86 87 // set operation88 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 operation93 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 type101 102 if( cmd_type == IOC_SYNC_READ ) // polling policy103 {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 completed110 {111 hal_remote_sw( XPTR( th_cxy , &th_ptr->command.ioc.error ) , 0 );112 break;113 }114 else if( status == BDV_BUSY ) // non completed115 {116 continue;117 }118 else // error reported119 {120 hal_remote_sw( XPTR( th_cxy , &th_ptr->command.ioc.error ) , 1 );121 break;122 }123 }124 }125 else // descheduling + IRQ policy126 {127 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );128 sched_yield();129 }130 131 } // end soclib_bdv_cmd()132 133 134 /////////////////////////////////////////////////////////////////135 40 void __attribute__ ((noinline)) soclib_bdv_isr( chdev_t * chdev ) 136 41 { 137 // get extended pointer on client thread138 xptr_t root = XPTR( local_cxy , &chdev->wait_root );139 xptr_t client_xp = XLIST_FIRST_ELEMENT( root , thread_t , wait_list );140 42 141 // get extended pointer on server thread 142 xptr_t server_xp = XPTR( local_cxy , &chdev->server ); 43 } 143 44 144 // get client thread cluster and local pointer145 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 pointer149 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 IRQ153 uint32_t status = hal_remote_lw( XPTR( bdv_cxy , bdv_ptr + BDV_STATUS_REG ) );154 155 // set operation status in command156 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 else161 {162 hal_remote_sw( XPTR( client_cxy , &client_ptr->command.ioc.error ) , 0 );163 }164 165 // unblock server thread166 thread_unblock( server_xp , THREAD_BLOCKED_DEV_ISR );167 168 // unblock client thread169 thread_unblock( client_xp , THREAD_BLOCKED_IO );170 171 } // end soclib_bdv_isr()172 173 174
Note: See TracChangeset
for help on using the changeset viewer.