Changes in trunk/kernel/devices/dev_nic.c [3:1]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/devices/dev_nic.c
r3 r1 25 25 #include <hal_special.h> 26 26 #include <printk.h> 27 #include < chdev.h>27 #include <device.h> 28 28 #include <thread.h> 29 29 #include <soclib_nic.h> … … 34 34 ///////////////////////////////////////////////////////////////////////////////////////// 35 35 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 ) 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 ) 42 43 { 43 // the local ICU chdev must be initialized before the NIC chdev, because44 // the NIC chdevs initialisation requires allocation of a WTI from local ICU45 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 descriptor49 uint32_t i mpl = chdev->impl;50 uint32_t is_rx = chdev->is_rx;51 uint32_t channel = chdev->channel; 52 53 // set driver specific fields in chdev descriptorand call driver init function44 // get device descriptor cluster and local pointer 45 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 is_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 function 54 55 if( impl == IMPL_NIC_SOC ) 55 56 { 56 chdev->cmd = &soclib_nic_cmd; 57 chdev->isr = &soclib_nic_isr; 58 soclib_nic_init( chdev ); 59 } 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 // } 60 71 else 61 72 { 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 ); 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 ); 75 96 76 97 // link NIC IRQ to WTI mailbox in PIC component 77 98 uint32_t irq_id; 78 if( is_rx ) irq_id = chdev_pic_input.nic_rx[channel];79 else irq_id = chdev_pic_input.nic_tx[channel];99 if( is_rx ) irq_id = devices_input_irq.nic_rx[channel]; 100 else irq_id = devices_input_irq.nic_tx[channel]; 80 101 dev_pic_bind_irq( irq_id , local_cxy , wti_id ); 81 102 82 103 // create server thread 83 thread_t * new_thread; 104 thread_t * new_thread_ptr; 105 xptr_t new_thread_xp; 84 106 error_t error; 85 107 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; 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 ); 96 137 97 138 // start server thread 98 thread_unblock( XPTR( local_cxy , new_thread ), THREAD_BLOCKED_GLOBAL );139 thread_unblock( new_thread_xp , THREAD_BLOCKED_GLOBAL ); 99 140 100 141 } // end dev_nic_init() … … 115 156 __FUNCTION__ , core->lid , local_cxy ); 116 157 117 // get pointer on NIC-RX chdevdescriptor158 // get pointer on NIC-RX device descriptor 118 159 uint32_t channel = thread_ptr->dev_channel; 119 xptr_t dev_xp = chdev_dir.nic_rx[channel];160 xptr_t dev_xp = devices_dir.nic_rx[channel]; 120 161 cxy_t dev_cxy = GET_CXY( dev_xp ); 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" ); 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 } 126 175 127 176 // initialize command in thread descriptor 128 thread_ptr-> command.nic.dev_xp = dev_xp;177 thread_ptr->dev.nic.dev_xp = dev_xp; 129 178 130 179 // call driver to test readable 131 thread_ptr-> command.nic.cmd = NIC_CMD_READABLE;180 thread_ptr->dev.nic.cmd = NIC_CMD_READABLE; 132 181 dev_ptr->cmd( thread_xp ); 133 182 134 183 // check error 135 error = thread_ptr-> command.nic.error;184 error = thread_ptr->dev.nic.error; 136 185 if( error ) return error; 137 186 138 187 // block and deschedule if queue non readable 139 if( thread_ptr-> command.nic.status == false )188 if( thread_ptr->dev.nic.status == false ) 140 189 { 141 190 // get NIC-RX IRQ index and type … … 144 193 145 194 // enable NIC-RX IRQ 146 dev_icu_enable_irq( core->lid , irq_type , irq_id , dev_ptr);195 dev_icu_enable_irq( local_cxy , core->lid , irq_type , irq_id , dev_xp ); 147 196 148 197 // block on THREAD_BLOCKED I/O condition and deschedule … … 151 200 152 201 // disable NIC-RX channel IRQ 153 dev_icu_disable_irq( core->lid , irq_type , irq_id );202 dev_icu_disable_irq( local_cxy , core->lid , irq_type , irq_id ); 154 203 } 155 204 156 205 // call driver for actual read 157 thread_ptr-> command.nic.cmd = NIC_CMD_READ;158 thread_ptr-> command.nic.buffer = pkd->buffer;206 thread_ptr->dev.nic.cmd = NIC_CMD_READ; 207 thread_ptr->dev.nic.buffer = pkd->buffer; 159 208 dev_ptr->cmd( thread_xp ); 160 209 161 210 // check error 162 error = thread_ptr-> command.nic.error;211 error = thread_ptr->dev.nic.error; 163 212 if( error ) return error; 164 213 165 214 // returns packet length 166 pkd->length = thread_ptr-> command.nic.length;215 pkd->length = thread_ptr->dev.nic.length; 167 216 168 217 nic_dmsg("\n[INFO] %s exit for NIC-RX thread on core %d in cluster %x\n", … … 189 238 __FUNCTION__ , core->lid , local_cxy ); 190 239 191 // get pointer on NIC-TX chdevdescriptor240 // get pointer on NIC-TX device descriptor 192 241 uint32_t channel = thread_ptr->dev_channel; 193 xptr_t dev_xp = chdev_dir.nic_tx[channel];242 xptr_t dev_xp = devices_dir.nic_tx[channel]; 194 243 cxy_t dev_cxy = GET_CXY( dev_xp ); 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" ); 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 } 200 257 201 258 // initialize command in thread descriptor 202 thread_ptr-> command.nic.dev_xp = dev_xp;259 thread_ptr->dev.nic.dev_xp = dev_xp; 203 260 204 261 // call driver to test writable 205 thread_ptr-> command.nic.cmd = NIC_CMD_WRITABLE;262 thread_ptr->dev.nic.cmd = NIC_CMD_WRITABLE; 206 263 dev_ptr->cmd( thread_xp ); 207 264 208 265 // check error 209 error = thread_ptr-> command.nic.error;266 error = thread_ptr->dev.nic.error; 210 267 if( error ) return error; 211 268 212 269 // block and deschedule if queue non writable 213 if( thread_ptr-> command.nic.status == false )270 if( thread_ptr->dev.nic.status == false ) 214 271 { 215 272 // get NIC-TX IRQ index and type … … 218 275 219 276 // enable NIC-TX IRQ 220 dev_icu_enable_irq( core->lid , irq_type , irq_id , dev_ptr);277 dev_icu_enable_irq( local_cxy , core->lid , irq_type , irq_id , dev_xp ); 221 278 222 279 // block on THREAD_BLOCKED I/O condition and deschedule … … 225 282 226 283 // disable NIC-TX IRQ 227 dev_icu_disable_irq( core->lid , irq_type , irq_id );284 dev_icu_disable_irq( local_cxy , core->lid , irq_type , irq_id ); 228 285 } 229 286 230 287 // call driver for actual write 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;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; 234 291 dev_ptr->cmd( thread_xp ); 235 292 236 293 // check error 237 error = thread_ptr-> command.nic.error;294 error = thread_ptr->dev.nic.error; 238 295 if( error ) return error; 239 296
Note: See TracChangeset
for help on using the changeset viewer.