Changeset 23 for trunk/kernel/drivers
- Timestamp:
- Jun 18, 2017, 10:06:41 PM (7 years ago)
- Location:
- trunk/kernel/drivers/soclib
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/drivers/soclib/soclib_bdv.c
r4 r23 53 53 void __attribute__ ((noinline)) soclib_bdv_cmd( xptr_t th_xp ) 54 54 { 55 uint32_t to_mem; // command argument55 uint32_t cmd_type; // IOC_READ / IOC_WRITE / IOC_SYNC_READ 56 56 uint32_t lba; // command argument 57 57 uint32_t count; // command argument … … 64 64 65 65 // get command arguments and extended pointer on IOC device 66 to_mem = hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.to_mem) );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 ) );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 71 72 72 // get IOC device cluster and local pointer … … 85 85 uint32_t buf_msb = (uint32_t)(buf_xp>>32); 86 86 87 // get access type 88 uint32_t type = to_mem ? BDV_OP_READ : BDV_OP_WRITE; 87 // set operation 88 uint32_t op; 89 if( cmd_type == IOC_WRITE ) op = BDV_OP_WRITE; 90 else op = BDV_OP_READ; 89 91 90 92 // set SOCLIB_BDV registers to start one I/O operation … … 94 96 hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_LBA_REG ) , lba ); 95 97 hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_COUNT_REG ) , count ); 96 hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_OP_REG ) , type);98 hal_remote_sw( XPTR( bdv_cxy , bdv_ptr + BDV_OP_REG ) , op ); 97 99 98 // Block and deschedule server thread 99 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR ); 100 sched_yield(); 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 } 101 130 102 131 } // end soclib_bdv_cmd() -
trunk/kernel/drivers/soclib/soclib_hba.c
r4 r23 72 72 chdev->ext.ioc.count = block_count; 73 73 74 // reset SOCLIB_HBA driver global variables 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 75 78 hba_active_slots = 0; 76 79 … … 78 81 79 82 80 ////////////////////////////////////////////////////////////// ////81 void __attribute__ ((noinline)) soclib_hba_c ommand( xptr_t th_xp )83 ////////////////////////////////////////////////////////////// 84 void __attribute__ ((noinline)) soclib_hba_cmd( xptr_t th_xp ) 82 85 { 83 86 84 uint32_t to_mem; // to_mem : command argument87 uint32_t cmd_type; // IOC_READ / IOC_WRITE / IOC_SYNC_READ 85 88 uint32_t lba; // lba : command argument 86 89 uint32_t count; // count : command argument 87 90 xptr_t buf_xp; // buffer : command argument 88 91 xptr_t dev_xp; // device : command argument 92 89 93 uint32_t cmd_id; // current slot index in command bit_vector 90 94 hba_cmd_desc_t * cmd_desc; // command descriptor pointer 91 95 hba_cmd_table_t * cmd_table; // command table pointer 96 92 97 bool_t found; 93 98 uint32_t iter; … … 98 103 99 104 // get command arguments and extended pointer on IOC device 100 to_mem = hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.to_mem) );105 cmd_type = hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.type ) ); 101 106 lba = hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.lba ) ); 102 107 count = hal_remote_lw ( XPTR( th_cxy , &th_ptr->command.ioc.count ) ); … … 135 140 } 136 141 137 if( found ) // register and starts the I/O operation142 if( found ) // slot available in SOCLIB_HBA 138 143 { 139 144 // compute pointers on command descriptor and command table … … 157 162 cmd_desc->prdtl[0] = 1; 158 163 cmd_desc->prdtl[1] = 0; 159 if( to_mem ) cmd_desc->flag[0] = 0x00;160 else cmd_desc->flag[0] = 0x40;164 if( cmd_type == IOC_WRITE ) cmd_desc->flag[0] = 0x40; 165 else cmd_desc->flag[0] = 0x00; 161 166 162 167 #if USE_IOB // software L2/L3 cache coherence 163 168 164 // compute physical addresses 165 paddr_t cmd_desc_paddr; // command descriptor physical address 166 paddr_t cmd_table_paddr; // command table header physical address 167 bool_t ident = CONFIG_KERNEL_IDENTITY; 168 169 error = vmm_v2p_translate( ident , cmd_table , &cmd_table_paddr ); 170 if( error ) 171 { 172 printk("\n[PANIC] in %s : cannot get paddr fo cmd_table\n", __FUNCTION__ ); 173 hal_core_sleep() 174 } 175 176 error = vmm_v2p_translate( ident , cmd_desc , &cmd_desc_paddr ); 177 if( error ) 178 { 179 printk("\n[PANIC] in %s : cannot get paddr fo cmd_desc\n", __FUNCTION__ ); 180 hal_core_sleep() 181 } 182 183 // update L3 for command table 184 dev_mmc_sync( cmd_table_paddr , sizeof(hba_cmd_table_t) ); 185 186 // update L3 for command descriptor 187 dev_mmc_sync( cmd_desc_paddr , sizeof(hba_cmd_desc_t) ); 169 dev_mmc_sync( cmd_table , sizeof(hba_cmd_table_t) ); 170 dev_mmc_sync( cmd_desc , sizeof(hba_cmd_desc_t) ); 188 171 189 172 #endif // end software L2/L3 cache coherence 190 191 // activates HBA interrupts192 hal_remote_sw( XPTR( hba_cxy , hba_ptr + HBA_PXIE_REG ) , 0x1 );193 173 194 174 // set hba_owner_thread[slot] 195 175 hba_owner_thread[cmd_id] = th_xp; 196 176 177 // register slot in bit_vector 178 hba_active_slots |= 1<<cmd_id; 179 197 180 // set HBA_PXCI_REG to start transfer 198 181 hal_remote_sw( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) , 1<<cmd_id ); 199 182 200 ioc_dmsg("INFO in %s : thread %x / buffer = %llx at cycle %d\n",201 __FUNCTION__ , hal_remote_lw( XPTR( th_cxy , &th_ptr->trdid ) ) ,202 buf_xp , hal_time_stamp() );203 204 183 // exit the while 205 184 break; 206 185 } 207 else // deschedule if no slot available in SOCLIB_HBA 208 { 209 sched_yield(); 210 } 211 } // end while 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 } 212 240 213 241 } // end soclib_hba_cmd() … … 229 257 uint32_t * hba_ptr = (uint32_t *)GET_PTR( chdev->base ); 230 258 231 // get HBA_PXIS_REG and HBA_PX IS_REG current values259 // get HBA_PXIS_REG and HBA_PXCI_REG current values 232 260 uint32_t current_pxis = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXIS_REG ) ); 233 261 uint32_t current_pxci = hal_remote_lw( XPTR( hba_cxy , hba_ptr + HBA_PXCI_REG ) ); -
trunk/kernel/drivers/soclib/soclib_hba.h
r4 r23 145 145 * @ xp_thread : extended pointer on the client thread. 146 146 *******************************************************************************************/ 147 extern void soclib_hba_c ommand( xptr_t thread_xp );147 extern void soclib_hba_cmd( xptr_t thread_xp ); 148 148 149 149 /********************************************************************************************
Note: See TracChangeset
for help on using the changeset viewer.