Changeset 3 for trunk/kernel/devices/dev_nic.c
- Timestamp:
- Apr 26, 2017, 2:08:13 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/devices/dev_nic.c
r1 r3 25 25 #include <hal_special.h> 26 26 #include <printk.h> 27 #include < device.h>27 #include <chdev.h> 28 28 #include <thread.h> 29 29 #include <soclib_nic.h> … … 34 34 ///////////////////////////////////////////////////////////////////////////////////////// 35 35 36 extern devices_directory_t devices_dir; // allocated in kernel_init.c 37 38 extern devices_input_irq_t devices_input_irq; // allocated in kernel_init.c 39 40 41 ////////////////////////////////// 42 void dev_nic_init( xptr_t dev_xp ) 36 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 37 38 extern chdev_pic_input_t chdev_pic_input; // allocated in kernel_init.c 39 40 //////////////////////////////////// 41 void dev_nic_init( chdev_t * chdev ) 43 42 { 44 // get device descriptor cluster and local pointer45 cxy_t dev_cxy = GET_CXY( dev_xp );46 device_t * dev_ptr = (device_t *)GET_PTR( dev_xp );47 48 // get "impl" , "channel" , "is_rx" fields from device descriptor 49 uint32_t impl = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->impl ) );50 uint32_t i s_rx = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->is_rx ) );51 uint32_t channel = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->channel ) );52 53 // set driver specific fields in device descriptor 54 // and call driver init function43 // the local ICU chdev must be initialized before the NIC chdev, because 44 // the NIC chdevs initialisation requires allocation of a WTI from local ICU 45 xptr_t icu_xp = chdev_dir.icu[local_cxy]; 46 assert( (icu_xp != XPTR_NULL) , __FUNCTION__ , "ICU not initialised before NIC" ); 47 48 // get "impl" , "channel" , "is_rx" fields from chdev descriptor 49 uint32_t impl = chdev->impl; 50 uint32_t is_rx = chdev->is_rx; 51 uint32_t channel = chdev->channel; 52 53 // set driver specific fields in chdev descriptor and call driver init function 55 54 if( impl == IMPL_NIC_SOC ) 56 55 { 57 hal_remote_spt( XPTR( dev_cxy , &dev_ptr->cmd ) , &soclib_nic_cmd ); 58 hal_remote_spt( XPTR( dev_cxy , &dev_ptr->isr ) , &soclib_nic_isr ); 59 hal_remote_memcpy( XPTR( dev_cxy , &dev_ptr->name ), 60 XPTR( local_cxy , "NIC_SOC" ) , 16 ); 61 soclib_nic_init( dev_xp ); 62 } 63 // else if( impl == IMPL_NIC_I86) 64 // { 65 // hal_remote_spt( XPTR( cxy , &ptr->cmd ) , &i86_nic_cmd ); 66 // hal_remote_spt( XPTR( cxy , &ptr->isr ) , &i86_nic_isr ); 67 // hal_remote_memcpy( XPTR( cxy , &ptr->name ), 68 // XPTR( local_cxy , "NIC_I86" ) , 16 ); 69 // i86_nic_init( dev ); 70 // } 56 chdev->cmd = &soclib_nic_cmd; 57 chdev->isr = &soclib_nic_isr; 58 soclib_nic_init( chdev ); 59 } 71 60 else 72 61 { 73 printk("\n[PANIC] in %s : undefined NIC device implementation\n", __FUNCTION__ ); 74 hal_core_sleep(); 75 } 76 77 // get a free WTI mailbox for this NIC device 78 uint32_t wti_id; 79 if( dev_cxy == local_cxy ) // NIC device cluster is local 80 { 81 wti_id = dev_icu_wti_alloc(); 82 } 83 else // NIC device cluster is remote 84 { 85 rpc_icu_wti_alloc_client( dev_cxy , &wti_id ); 86 } 87 88 if( wti_id == -1 ) 89 { 90 printk("\n[PANIC] in %s : cannot allocate WTI mailbox\n", __FUNCTION__ ); 91 hal_core_sleep(); 92 } 93 94 // enable WTI IRQ in remote ICU and update WTI interrupt vector 95 dev_icu_enable_irq( dev_cxy, 0 , WTI_TYPE , wti_id , dev_xp ); 62 assert( false , __FUNCTION__ , "undefined NIC device implementation" ); 63 } 64 65 // get a WTI mailbox from local ICU 66 uint32_t wti_id = dev_icu_wti_alloc(); 67 68 assert( (wti_id != -1) , __FUNCTION__ , "cannot allocate WTI mailbox" ); 69 70 // select a core 71 lid_t lid = cluster_select_local_core(); 72 73 // enable WTI IRQ and update WTI interrupt vector 74 dev_icu_enable_irq( lid , WTI_TYPE , wti_id , chdev ); 96 75 97 76 // link NIC IRQ to WTI mailbox in PIC component 98 77 uint32_t irq_id; 99 if( is_rx ) irq_id = devices_input_irq.nic_rx[channel];100 else irq_id = devices_input_irq.nic_tx[channel];78 if( is_rx ) irq_id = chdev_pic_input.nic_rx[channel]; 79 else irq_id = chdev_pic_input.nic_tx[channel]; 101 80 dev_pic_bind_irq( irq_id , local_cxy , wti_id ); 102 81 103 82 // create server thread 104 thread_t * new_thread_ptr; 105 xptr_t new_thread_xp; 83 thread_t * new_thread; 106 84 error_t error; 107 85 108 if( dev_cxy == local_cxy ) // device cluster is local 109 { 110 error = thread_kernel_create( &new_thread_ptr, 111 THREAD_DEV, 112 &dev_ioc_server, 113 dev_ptr, 114 cluster_select_local_core() ); 115 116 new_thread_xp = XPTR( local_cxy , new_thread_ptr ); 117 } 118 else // device cluster is remote 119 { 120 rpc_thread_kernel_create_client( dev_cxy, 121 THREAD_DEV, 122 &dev_ioc_server, 123 dev_ptr, 124 &new_thread_xp, 125 &error ); 126 127 new_thread_ptr = (thread_t *)GET_PTR( new_thread_xp ); 128 } 129 if( error ) 130 { 131 printk("\n[PANIC] in %s : cannot create server thread\n", __FUNCTION__ ); 132 hal_core_sleep(); 133 } 134 135 // set "server" field in device descriptor 136 hal_remote_spt( XPTR( dev_cxy , &dev_ptr->server ) , new_thread_ptr ); 86 error = thread_kernel_create( &new_thread, 87 THREAD_DEV, 88 &chdev_sequencial_server, 89 chdev, 90 lid ); 91 92 assert( (error == 0) , __FUNCTION__ , "cannot create server thread" ); 93 94 // set "server" field in chdev descriptor 95 chdev->server = new_thread; 137 96 138 97 // start server thread 139 thread_unblock( new_thread_xp, THREAD_BLOCKED_GLOBAL );98 thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL ); 140 99 141 100 } // end dev_nic_init() … … 156 115 __FUNCTION__ , core->lid , local_cxy ); 157 116 158 // get pointer on NIC-RX devicedescriptor117 // get pointer on NIC-RX chdev descriptor 159 118 uint32_t channel = thread_ptr->dev_channel; 160 xptr_t dev_xp = devices_dir.nic_rx[channel];119 xptr_t dev_xp = chdev_dir.nic_rx[channel]; 161 120 cxy_t dev_cxy = GET_CXY( dev_xp ); 162 device_t * dev_ptr = (device_t *)GET_PTR( dev_xp ); 163 164 if ( dev_xp == XPTR_NULL ) 165 { 166 printk("\n[PANIC] in %s : undefined NIC device descriptor\n", __FUNCTION__ ); 167 hal_core_sleep(); 168 } 169 170 if ( dev_cxy != local_cxy ) 171 { 172 printk("\n[PANIC] in %s : device descriptor must be local\n", __FUNCTION__ ); 173 hal_core_sleep(); 174 } 121 chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp ); 122 123 assert( (dev_xp != XPTR_NULL) , __FUNCTION__ , "undefined NIC chdev descriptor" ); 124 125 assert( (dev_cxy == local_cxy) , __FUNCTION__ , " chdev must be local" ); 175 126 176 127 // initialize command in thread descriptor 177 thread_ptr-> dev.nic.dev_xp = dev_xp;128 thread_ptr->command.nic.dev_xp = dev_xp; 178 129 179 130 // call driver to test readable 180 thread_ptr-> dev.nic.cmd = NIC_CMD_READABLE;181 dev_ptr->cmd( thread_xp ); 182 183 // check error 184 error = thread_ptr-> dev.nic.error;131 thread_ptr->command.nic.cmd = NIC_CMD_READABLE; 132 dev_ptr->cmd( thread_xp ); 133 134 // check error 135 error = thread_ptr->command.nic.error; 185 136 if( error ) return error; 186 137 187 138 // block and deschedule if queue non readable 188 if( thread_ptr-> dev.nic.status == false )139 if( thread_ptr->command.nic.status == false ) 189 140 { 190 141 // get NIC-RX IRQ index and type … … 193 144 194 145 // enable NIC-RX IRQ 195 dev_icu_enable_irq( local_cxy , core->lid , irq_type , irq_id , dev_xp);146 dev_icu_enable_irq( core->lid , irq_type , irq_id , dev_ptr ); 196 147 197 148 // block on THREAD_BLOCKED I/O condition and deschedule … … 200 151 201 152 // disable NIC-RX channel IRQ 202 dev_icu_disable_irq( local_cxy ,core->lid , irq_type , irq_id );153 dev_icu_disable_irq( core->lid , irq_type , irq_id ); 203 154 } 204 155 205 156 // call driver for actual read 206 thread_ptr-> dev.nic.cmd = NIC_CMD_READ;207 thread_ptr-> dev.nic.buffer = pkd->buffer;208 dev_ptr->cmd( thread_xp ); 209 210 // check error 211 error = thread_ptr-> dev.nic.error;157 thread_ptr->command.nic.cmd = NIC_CMD_READ; 158 thread_ptr->command.nic.buffer = pkd->buffer; 159 dev_ptr->cmd( thread_xp ); 160 161 // check error 162 error = thread_ptr->command.nic.error; 212 163 if( error ) return error; 213 164 214 165 // returns packet length 215 pkd->length = thread_ptr-> dev.nic.length;166 pkd->length = thread_ptr->command.nic.length; 216 167 217 168 nic_dmsg("\n[INFO] %s exit for NIC-RX thread on core %d in cluster %x\n", … … 238 189 __FUNCTION__ , core->lid , local_cxy ); 239 190 240 // get pointer on NIC-TX devicedescriptor191 // get pointer on NIC-TX chdev descriptor 241 192 uint32_t channel = thread_ptr->dev_channel; 242 xptr_t dev_xp = devices_dir.nic_tx[channel];193 xptr_t dev_xp = chdev_dir.nic_tx[channel]; 243 194 cxy_t dev_cxy = GET_CXY( dev_xp ); 244 device_t * dev_ptr = (device_t *)GET_PTR( dev_xp ); 245 246 if ( dev_xp == XPTR_NULL ) 247 { 248 printk("\n[PANIC] in %s : undefined NIC device descriptor\n", __FUNCTION__ ); 249 hal_core_sleep(); 250 } 251 252 if ( dev_cxy != local_cxy ) 253 { 254 printk("\n[PANIC] in %s : device descriptor must be local\n", __FUNCTION__ ); 255 hal_core_sleep(); 256 } 195 chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp ); 196 197 assert ( (dev_xp != XPTR_NULL) , __FUNCTION__ , "undefined NIC chdev descriptor" ); 198 199 assert( (dev_cxy == local_cxy) , __FUNCTION__ , " chdev must be local" ); 257 200 258 201 // initialize command in thread descriptor 259 thread_ptr-> dev.nic.dev_xp = dev_xp;202 thread_ptr->command.nic.dev_xp = dev_xp; 260 203 261 204 // call driver to test writable 262 thread_ptr-> dev.nic.cmd = NIC_CMD_WRITABLE;263 dev_ptr->cmd( thread_xp ); 264 265 // check error 266 error = thread_ptr-> dev.nic.error;205 thread_ptr->command.nic.cmd = NIC_CMD_WRITABLE; 206 dev_ptr->cmd( thread_xp ); 207 208 // check error 209 error = thread_ptr->command.nic.error; 267 210 if( error ) return error; 268 211 269 212 // block and deschedule if queue non writable 270 if( thread_ptr-> dev.nic.status == false )213 if( thread_ptr->command.nic.status == false ) 271 214 { 272 215 // get NIC-TX IRQ index and type … … 275 218 276 219 // enable NIC-TX IRQ 277 dev_icu_enable_irq( local_cxy , core->lid , irq_type , irq_id , dev_xp);220 dev_icu_enable_irq( core->lid , irq_type , irq_id , dev_ptr ); 278 221 279 222 // block on THREAD_BLOCKED I/O condition and deschedule … … 282 225 283 226 // disable NIC-TX IRQ 284 dev_icu_disable_irq( local_cxy ,core->lid , irq_type , irq_id );227 dev_icu_disable_irq( core->lid , irq_type , irq_id ); 285 228 } 286 229 287 230 // call driver for actual write 288 thread_ptr-> dev.nic.cmd = NIC_CMD_WRITE;289 thread_ptr-> dev.nic.buffer = pkd->buffer;290 thread_ptr-> dev.nic.length = pkd->length;291 dev_ptr->cmd( thread_xp ); 292 293 // check error 294 error = thread_ptr-> dev.nic.error;231 thread_ptr->command.nic.cmd = NIC_CMD_WRITE; 232 thread_ptr->command.nic.buffer = pkd->buffer; 233 thread_ptr->command.nic.length = pkd->length; 234 dev_ptr->cmd( thread_xp ); 235 236 // check error 237 error = thread_ptr->command.nic.error; 295 238 if( error ) return error; 296 239
Note: See TracChangeset
for help on using the changeset viewer.