Changeset 459
- Timestamp:
- Dec 5, 2014, 3:51:22 PM (10 years ago)
- Location:
- soft/giet_vm/giet_kernel
- Files:
-
- 2 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_kernel/ctx_handler.c
r440 r459 9 9 #include <giet_config.h> 10 10 #include <utils.h> 11 #include < kernel_utils.h>11 #include <tty0.h> 12 12 #include <xcu_driver.h> 13 13 -
soft/giet_vm/giet_kernel/exc_handler.c
r440 r459 10 10 #include <sys_handler.h> 11 11 #include <utils.h> 12 #include < kernel_utils.h>12 #include <tty0.h> 13 13 14 14 /////////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_kernel/irq_handler.c
r440 r459 21 21 #include <mapping_info.h> 22 22 #include <utils.h> 23 #include < kernel_utils.h>23 #include <tty0.h> 24 24 25 25 #if NB_TIM_CHANNELS -
soft/giet_vm/giet_kernel/kernel_init.c
r449 r459 11 11 #include <hard_config.h> 12 12 #include <utils.h> 13 #include < kernel_utils.h>13 #include <tty0.h> 14 14 #include <fat32.h> 15 15 #include <xcu_driver.h> 16 #include <ioc_driver.h> 16 17 #include <ctx_handler.h> 17 18 #include <irq_handler.h> … … 107 108 // This initialisation is done sequencially by each processor 108 109 while( cpid != kernel_init_barrier ) asm volatile ( "nop" ); 110 111 // Step 0 : Processor[0,0,0] initialises the kernel FAT 112 if ( gpid == 0 ) _fat_init( IOC_BOOT_MODE ); 109 113 110 114 // Step 1 : each processor get its scheduler virtual address from CP0_SCHED register -
soft/giet_vm/giet_kernel/sys_handler.c
r449 r459 16 16 #include <fat32.h> 17 17 #include <utils.h> 18 #include < kernel_utils.h>18 #include <tty0.h> 19 19 #include <vmem.h> 20 20 #include <hard_config.h> … … 30 30 #endif 31 31 32 #if (NB_TTY_CHANNELS < 1) 33 # error: NB_TTY_CHANNELS cannot be smaller than 1! 34 #endif 35 32 36 #if !defined(NB_TIM_CHANNELS) 33 37 # error: You must define NB_TIM_CHANNELS in the hard_config.h file … … 42 46 #endif 43 47 44 #if !defined(GIET_NIC_CHBUF_NBUFS) 45 # error: You must define GIET_NIC_CHBUF_NBUFS in the giet_config.h file 46 #endif 47 48 #if !defined(GIET_NIC_CHBUF_SIZE) 49 # error: You must define GIET_NIC_CHBUF_SIZE in the giet_config.h file 50 #endif 51 52 #if !defined(GIET_NIC_CHBUF_TIMEOUT) 53 # error: You must define GIET_NIC_CHBUF_TIMEOUT in the giet_config.h file 48 #if !defined(GIET_NIC_NBUFS) 49 # error: You must define GIET_NIC_NBUFS in the giet_config.h file 50 #endif 51 52 #if !defined(GIET_NIC_BUFSIZE) 53 # error: You must define GIET_NIC_BUFSIZE in the giet_config.h file 54 #endif 55 56 #if !defined(GIET_NIC_TIMEOUT) 57 # error: You must define GIET_NIC_TIMEOUT in the giet_config.h file 58 #endif 59 60 #if !defined(GIET_NO_HARD_CC) 61 # error: You must define GIET_NO_HARD_CC in the giet_config.h file 54 62 #endif 55 63 … … 66 74 unsigned int _nic_tx_channel_allocator = 0; 67 75 68 69 76 //////////////////////////////////////////////////////////////////////////// 70 // NIC_RX and NIC_TX chbuf arrays 77 // NIC_RX and NIC_TX chbuf arrays and associated containers arrays 71 78 //////////////////////////////////////////////////////////////////////////// 72 79 73 nic_chbuf_t _nic_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(8))); 74 nic_chbuf_t _nic_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(8))); 75 80 spin_lock_t _nic_rx_lock[NB_NIC_CHANNELS] __attribute__((aligned(64))); 81 82 spin_lock_t _nic_tx_lock[NB_NIC_CHANNELS] __attribute__((aligned(64))); 83 84 nic_chbuf_t _nic_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64))); 85 86 nic_chbuf_t _nic_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64))); 87 88 unsigned char _nic_rx_cont[GIET_NIC_BUFSIZE] 89 [GIET_NIC_NBUFS] 90 [NB_NIC_CHANNELS] __attribute__((aligned(64))); 91 92 unsigned char _nic_tx_cont[GIET_NIC_BUFSIZE] 93 [GIET_NIC_NBUFS] 94 [NB_NIC_CHANNELS] __attribute__((aligned(64))); 76 95 77 96 //////////////////////////////////////////////////////////////////////////// … … 133 152 134 153 &_sys_nic_alloc, /* 0x30 */ 135 &_sys_nic_ alloc, /* 0x31 */136 &_sys_nic_ start,/* 0x32 */137 &_sys_nic_st art,/* 0x33 */138 &_sys_nic_ move,/* 0x34 */139 &_sys_nic_ move,/* 0x35 */140 &_sys_ nic_stop,/* 0x36 */141 &_sys_ nic_stop,/* 0x37 */154 &_sys_nic_start, /* 0x31 */ 155 &_sys_nic_move, /* 0x32 */ 156 &_sys_nic_stop, /* 0x33 */ 157 &_sys_nic_stats, /* 0x34 */ 158 &_sys_nic_clear, /* 0x35 */ 159 &_sys_ukn, /* 0x36 */ 160 &_sys_ukn, /* 0x37 */ 142 161 &_sys_ukn, /* 0x38 */ 143 162 &_sys_ukn, /* 0x39 */ … … 150 169 }; 151 170 171 152 172 ////////////////////////////////////////////////////////////////////////////// 153 173 // TTY related syscall handlers … … 158 178 { 159 179 // get a new TTY terminal index 160 unsigned int channel = _atomic_increment( &_tty_channel_allocator );180 unsigned int channel = _atomic_increment( &_tty_channel_allocator, 1 ); 161 181 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 162 182 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); … … 235 255 236 256 _it_disable( save_sr_ptr ); 237 _ get_lock( &_tty_lock[channel] );257 _simple_lock_acquire( &_tty_tx_lock[channel] ); 238 258 return 0; 239 259 } … … 247 267 if( channel >= NB_TTY_CHANNELS ) return -1; 248 268 249 _ release_lock( &_tty_lock[channel] );269 _simple_lock_release( &_tty_tx_lock[channel] ); 250 270 _it_restore( save_sr_ptr ); 251 271 return 0; … … 260 280 { 261 281 // get a new timer index 262 unsigned int channel = _atomic_increment( &_tim_channel_allocator);282 unsigned int channel = _atomic_increment( &_tim_channel_allocator, 1 ); 263 283 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 264 284 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); … … 319 339 int _sys_nic_alloc( unsigned int is_rx ) 320 340 { 321 unsigned int nic_channel;322 unsigned int cma_channel;323 324 // get a NIC_RX or NIC_TX channel index325 if ( is_rx ) nic_channel = _atomic_increment(&_nic_rx_channel_allocator);326 else nic_channel = _atomic_increment(&_nic_tx_channel_allocator);327 328 if ( (nic_channel >= NB_NIC_CHANNELS) )329 {330 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n");331 return -1;332 }333 334 // get a CMA channel index335 cma_channel = _atomic_increment(&_cma_channel_allocator);336 337 if ( cma_channel >= NB_CMA_CHANNELS )338 {339 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n");340 return -1;341 }342 343 // register nic_index and cma_index in task context344 if ( is_rx )345 {346 _set_context_slot( CTX_NIC_RX_ID, nic_channel );347 _set_context_slot( CTX_CMA_RX_ID, cma_channel );348 }349 else350 {351 _set_context_slot( CTX_NIC_TX_ID, nic_channel );352 _set_context_slot( CTX_CMA_TX_ID, cma_channel );353 }354 341 355 342 #if GIET_DEBUG_NIC 356 343 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 357 344 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); 358 _printf("\n[GIET DEBUG_NIC] NIC channel %d and CMA channel %d" 359 " allocated to task %d in vspace %d\n", 360 nic_channel, cma_channel, thread, vspace ); 361 #endif 362 363 return 0; 364 } 365 366 //////////////////////////////////////// 367 int _sys_nic_start( unsigned int is_rx, 368 unsigned int mac4, 369 unsigned int mac2 ) 370 { 345 _printf("\n[GIET DEBUG NIC] Task %d in vspace %d enters sys_nic_alloc()\n", 346 thread, vspace ); 347 #endif 348 371 349 unsigned int nic_channel; 372 350 unsigned int cma_channel; 373 351 352 // get a NIC_RX or NIC_TX channel index 353 if ( is_rx ) nic_channel = _atomic_increment( &_nic_rx_channel_allocator, 1 ); 354 else nic_channel = _atomic_increment( &_nic_tx_channel_allocator, 1 ); 355 356 if ( (nic_channel >= NB_NIC_CHANNELS) ) 357 { 358 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n"); 359 return -1; 360 } 361 362 // get a CMA channel index 363 cma_channel = _atomic_increment( &_cma_channel_allocator, 1 ); 364 365 if ( cma_channel >= NB_CMA_CHANNELS ) 366 { 367 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n"); 368 return -1; 369 } 370 371 // register nic_index and cma_index in task context 372 if ( is_rx ) 373 { 374 _set_context_slot( CTX_NIC_RX_ID, nic_channel ); 375 _set_context_slot( CTX_CMA_RX_ID, cma_channel ); 376 } 377 else 378 { 379 _set_context_slot( CTX_NIC_TX_ID, nic_channel ); 380 _set_context_slot( CTX_CMA_TX_ID, cma_channel ); 381 } 382 383 #if GIET_DEBUG_NIC 384 _printf("\n[GIET DEBUG NIC] Task %d in vspace %d exit _sys_nic_alloc() : " 385 "NIC channel = %d / CMA channel = %d\n", 386 thread, vspace, nic_channel, cma_channel ); 387 #endif 388 389 return nic_channel; 390 } // end _sys_nic_alloc() 391 392 //////////////////////////////////////// 393 int _sys_nic_start( unsigned int is_rx ) 394 { 395 396 #if GIET_DEBUG_NIC 397 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 398 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); 399 _printf("\n[GIET DEBUG NIC] Task %d of vspace %d enters _sys_nic_start()\n", 400 thread, vspace ); 401 #endif 402 403 unsigned int nic_channel; 404 unsigned int cma_channel; 405 374 406 // get NIC channel index and CMA channel index 375 407 if ( is_rx ) … … 384 416 } 385 417 418 #if GIET_DEBUG_NIC 419 _printf("\n[GIET DEBUG NIC] Task %d of vspace %d in _sys_nic_start()" 420 " get NIC channel = %d / CMA channel = %d\n", 421 thread, vspace, nic_channel, cma_channel ); 422 #endif 423 386 424 if ( nic_channel >= NB_NIC_CHANNELS ) 387 425 { … … 395 433 } 396 434 397 unsigned int nic_chbuf_lsb; // 32 LSB bits of the NIC chbuf physical address 398 unsigned int nic_chbuf_msb; // 16 MSB bits of the NIC chbuf physical address 399 unsigned int ker_chbuf_lsb; // 32 LSB bits of the kernel chbuf physical address 400 unsigned int ker_chbuf_msb; // 16 MSB bits of the kernel chbuf physical address 435 unsigned long long nic_chbuf_pbase; // NIC chbuf physical address 436 unsigned long long ker_chbuf_pbase; // kernel chbuf physical address 437 unsigned long long ker_cont_pbase; // kernel container array physical address 438 439 // These variables are used for V2P translation 440 unsigned int ptab = _get_context_slot(CTX_PTAB_ID); 441 unsigned int ppn; 442 unsigned int flags; 443 unsigned int ko; 444 unsigned int vaddr; 401 445 402 446 // get the NIC chbuf descriptor physical address 403 447 unsigned int offset; 404 if ( is_rx ) offset = 0x1000; 405 else offset = 0x1010; 406 nic_chbuf_lsb = SEG_NIC_BASE + (nic_channel * NIC_CHANNEL_SPAN) + offset; 407 nic_chbuf_msb = (X_IO << Y_WIDTH) + Y_IO; 408 409 // get the kernel chbuf descriptor physical address 410 unsigned int ker_chbuf_vaddr; 411 if ( is_rx ) ker_chbuf_vaddr = (unsigned int)( &_nic_rx_chbuf[nic_channel] ); 412 else ker_chbuf_vaddr = (unsigned int)( &_nic_tx_chbuf[nic_channel] ); 448 if ( is_rx ) offset = 0x4000; 449 else offset = 0x4010; 450 nic_chbuf_pbase = (((unsigned long long)((X_IO << Y_WIDTH) + Y_IO))<<32) | 451 (SEG_NIC_BASE + (nic_channel<<15) + offset); 452 453 #if GIET_DEBUG_NIC 454 _printf("\n[GIET DEBUG NIC] Task %d of vspace %d in _sys_nic_start()" 455 " get NIC chbuf paddr = %l\n", 456 thread, vspace, nic_chbuf_pbase ); 457 #endif 413 458 414 459 // compute the kernel chbuf descriptor physical address 415 unsigned int ppn; 416 unsigned int flags; 417 unsigned int ptab = _get_context_slot(CTX_PTAB_ID); 418 unsigned int ko = _v2p_translate( (page_table_t*)ptab, 419 ker_chbuf_vaddr, 420 &ppn, 421 &flags ); 460 if ( is_rx ) vaddr = (unsigned int)( &_nic_rx_chbuf[nic_channel] ); 461 else vaddr = (unsigned int)( &_nic_tx_chbuf[nic_channel] ); 462 ko = _v2p_translate( (page_table_t*)ptab, 463 vaddr>>12, 464 &ppn, 465 &flags ); 422 466 if ( ko ) 423 467 { 424 _puts("\n[GIET ERROR] in _nic_cma_start_receive() : kernel buffer unmapped\n"); 425 return -1; 426 } 427 428 ker_chbuf_lsb = (ppn << 12) | (ker_chbuf_vaddr & 0x00000FFF); 429 ker_chbuf_msb = ppn >> 20; 430 431 // initializes CMA registers defining the source chbuf (NIc) 432 _cma_set_register( cma_channel, CHBUF_SRC_DESC , nic_chbuf_lsb ); 433 _cma_set_register( cma_channel, CHBUF_DST_EXT , nic_chbuf_msb ); 434 _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, 2 ); 435 436 // initializes CMA registers defining the destination chbuf (kernel) 437 _cma_set_register( cma_channel, CHBUF_DST_DESC , ker_chbuf_lsb ); 438 _cma_set_register( cma_channel, CHBUF_DST_EXT , ker_chbuf_msb ); 439 _cma_set_register( cma_channel, CHBUF_DST_NBUFS, GIET_NIC_CHBUF_NBUFS ); 468 _puts("\n[GIET ERROR] in _sys_nic_start() : kernel chbuf unmapped\n"); 469 return -1; 470 } 471 ker_chbuf_pbase = (((unsigned long long)ppn) << 12) | (vaddr & 0x00000FFF); 472 473 #if GIET_DEBUG_NIC 474 _printf("\n[GIET DEBUG NIC] Task %d of vspace %d in _sys_nic_start()" 475 " get kernel chbuf paddr = %l\n", 476 thread, vspace, ker_chbuf_pbase ); 477 #endif 478 479 // compute the container array physical address 480 if ( is_rx ) vaddr = ((unsigned int)&_nic_rx_cont[0][0][nic_channel]); 481 else vaddr = ((unsigned int)&_nic_tx_cont[0][0][nic_channel]); 482 ko = _v2p_translate( (page_table_t*)ptab, 483 vaddr>>12, 484 &ppn, 485 &flags ); 486 if ( ko ) 487 { 488 _puts("\n[GIET ERROR] in _sys_nic_start() : containers array unmapped\n"); 489 return -1; 490 } 491 ker_cont_pbase = (((unsigned long long)ppn) << 12) | (vaddr & 0x00000FFF); 492 493 #if GIET_DEBUG_NIC 494 _printf("\n[GIET DEBUG NIC] Task %d of vspace %d in _sys_nic_start()" 495 " get kernel containers array paddr = %l\n", 496 thread, vspace, ker_cont_pbase ); 497 #endif 498 499 // initializes the kernel chbuf descriptor 500 unsigned int index; 501 if ( is_rx ) 502 { 503 _lock_init( &_nic_rx_lock[nic_channel] ); 504 _nic_rx_chbuf[nic_channel].index = 0; 505 for( index = 0 ; index < GIET_NIC_NBUFS ; index++ ) 506 { 507 _nic_rx_chbuf[nic_channel].buffer[index] = ker_cont_pbase + (index<<12); 508 } 509 } 510 else 511 { 512 _lock_init( &_nic_tx_lock[nic_channel] ); 513 _nic_tx_chbuf[nic_channel].index = 0; 514 for( index = 0 ; index < GIET_NIC_NBUFS ; index++ ) 515 { 516 _nic_tx_chbuf[nic_channel].buffer[index] = ker_cont_pbase + (index<<12); 517 } 518 } 519 520 // sync the kernel chbuf in L2 after write in L2 521 _mmc_sync( ker_chbuf_pbase, sizeof( nic_chbuf_t ) ); 522 523 // initializes CMA registers defining the source & destination chbufs 524 if ( is_rx ) // NIC to kernel 525 { 526 _cma_set_register( cma_channel, CHBUF_SRC_DESC , (unsigned int)(nic_chbuf_pbase) ); 527 _cma_set_register( cma_channel, CHBUF_SRC_EXT , (unsigned int)(nic_chbuf_pbase>>32) ); 528 _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, 2 ); 529 _cma_set_register( cma_channel, CHBUF_DST_DESC , (unsigned int)(ker_chbuf_pbase) ); 530 _cma_set_register( cma_channel, CHBUF_DST_EXT , (unsigned int)(ker_chbuf_pbase>>32) ); 531 _cma_set_register( cma_channel, CHBUF_DST_NBUFS, GIET_NIC_NBUFS ); 532 } 533 else // kernel to NIC 534 { 535 _cma_set_register( cma_channel, CHBUF_SRC_DESC , (unsigned int)(ker_chbuf_pbase) ); 536 _cma_set_register( cma_channel, CHBUF_SRC_EXT , (unsigned int)(ker_chbuf_pbase>>32) ); 537 _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, GIET_NIC_NBUFS ); 538 _cma_set_register( cma_channel, CHBUF_DST_DESC , (unsigned int)(nic_chbuf_pbase) ); 539 _cma_set_register( cma_channel, CHBUF_DST_EXT , (unsigned int)(nic_chbuf_pbase>>32) ); 540 _cma_set_register( cma_channel, CHBUF_DST_NBUFS, 2 ); 541 } 440 542 441 543 // start CMA transfer … … 445 547 446 548 // activates NIC channel 447 _nic_channel_start( nic_channel, is_rx, mac4, mac2 ); 448 return 0; 449 } 549 _nic_channel_start( nic_channel, is_rx, GIET_NIC_MAC4, GIET_NIC_MAC2 ); 550 551 #if GIET_DEBUG_NIC 552 _printf("\n[GIET DEBUG NIC] Task %d of vspace %d exit _sys_nic_start()\n", 553 thread, vspace ); 554 #endif 555 556 return 0; 557 } // end sys_nic_start() 450 558 451 559 ////////////////////////////////////// 452 560 int _sys_nic_move( unsigned int is_rx, 561 unsigned int channel, 453 562 void* buffer ) 454 563 { 455 unsigned long long user_paddr; // user buffer physical address 456 unsigned long long kernel_paddr; // kernel buffer physical address 457 458 // Compute user buffer physical address and check access rights 564 565 #if GIET_DEBUG_NIC 566 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 567 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); 568 _printf("\n[GIET DEBUG NIC] Task %d of vspace %d enters _sys_nic_move()\n", 569 thread, vspace ); 570 #endif 571 572 unsigned long long user_buffer_paddr; // user buffer physical address 573 unsigned long long kernel_buffer_paddr; // kernel buffer physical address 574 unsigned long long kernel_chbuf_paddr; // kernel chbuf physical address 575 unsigned long long kernel_buffer_desc; // kernel buffer descriptor 576 577 // The following variables are used for V2P translation 578 unsigned int ptab = _get_context_slot( CTX_PTAB_ID ); 459 579 unsigned int ppn; 460 580 unsigned int flags; 461 unsigned int vaddr = (unsigned int)buffer; 462 unsigned int user_ptab = _get_context_slot( CTX_PTAB_ID ); 463 unsigned int ko = _v2p_translate( (page_table_t*)user_ptab, 464 vaddr, 465 &ppn, 466 &flags ); 581 unsigned int vaddr; 582 unsigned int ko; 583 584 // Compute user buffer physical address and check access rights 585 vaddr = (unsigned int)buffer; 586 ko = _v2p_translate( (page_table_t*)ptab, 587 vaddr>>12, 588 &ppn, 589 &flags ); 467 590 if ( ko ) 468 591 { 469 _printf("\n[GIET ERROR] in _sys_nic_ tx_move() : user buffer unmapped\n");592 _printf("\n[GIET ERROR] in _sys_nic_move() : user buffer unmapped\n"); 470 593 return -1; 471 594 } … … 475 598 return -1; 476 599 } 477 user_paddr = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF); 478 479 // get NIC channel index, to get pointer on NIC_TX chbuf pointer 480 unsigned int channel; 481 if ( is_rx ) channel = _get_context_slot( CTX_NIC_RX_ID ); 482 else channel = _get_context_slot( CTX_NIC_TX_ID ); 483 600 user_buffer_paddr = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF); 601 602 #if GIET_DEBUG_NIC 603 _printf("\n[GIET DEBUG NIC] Task %d of vspace %d in _sys_nic_move()" 604 " get user buffer paddr = %l\n", 605 thread, vspace, user_buffer_paddr ); 606 #endif 607 608 // check NIC channel index 484 609 if ( channel >= NB_NIC_CHANNELS ) 485 610 { … … 488 613 } 489 614 615 // get kernel chbuf and lock addresses 490 616 nic_chbuf_t* chbuf; 491 if ( is_rx ) chbuf = &_nic_rx_chbuf[channel]; 492 else chbuf = &_nic_tx_chbuf[channel]; 493 494 // polling on the chbuf status 495 volatile unsigned long long desc; 617 spin_lock_t* lock; 618 619 if ( is_rx ) 620 { 621 chbuf = &_nic_rx_chbuf[channel]; 622 lock = &_nic_rx_lock[channel]; 623 } 624 else 625 { 626 chbuf = &_nic_tx_chbuf[channel]; 627 lock = &_nic_tx_lock[channel]; 628 } 629 630 // compute kernel chbuf physical address (required for sync) 631 vaddr = (unsigned int)chbuf; 632 ko = _v2p_translate( (page_table_t*)ptab, 633 vaddr>>12, 634 &ppn, 635 &flags ); 636 if ( ko ) 637 { 638 _printf("\n[GIET ERROR] in _sys_nic_move() : kernel chbuf unmapped\n"); 639 return -1; 640 } 641 kernel_chbuf_paddr = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF); 642 643 // get the lock protecting the chbuf 644 _lock_acquire( lock ); 645 646 // polling on the kernel chbuf status 496 647 unsigned int full; 497 648 unsigned int ok = 0; 498 649 unsigned int index = chbuf->index; 499 unsigned int timeout = GIET_NIC_ CHBUF_TIMEOUT;650 unsigned int timeout = GIET_NIC_TIMEOUT; 500 651 while( ok == 0 ) 501 652 { 502 desc = chbuf->buffer[index]; 503 full = desc >> 63; 504 if ( (is_rx && full) || ((is_rx == 0) && (full == 0)) ) // success 505 { 506 ok = 1; 507 } 508 else // retry 509 { 510 timeout--; 511 } 653 // inval kernel chbuf in L2 before read in L2 654 _mmc_inval( kernel_chbuf_paddr, sizeof( nic_chbuf_t ) ); 655 656 // get kernel buffer descriptor 657 kernel_buffer_desc = chbuf->buffer[index]; 658 659 #if GIET_DEBUG_NIC 660 _printf("\n[GIET DEBUG NIC] Task %d of vspace %d in _sys_nic_move()" 661 " poll kernel container descriptor = %l\n", 662 thread, vspace, kernel_buffer_desc ); 663 #endif 664 665 full = kernel_buffer_desc >> 63; 666 if ( (is_rx && full) || ((is_rx == 0) && (full == 0)) ) ok = 1; 667 else timeout--; 668 512 669 if ( timeout == 0 ) 513 670 { 514 _printf("\n[GIET_ERROR] in _sys_ni _move() : timeout\n");671 _printf("\n[GIET_ERROR] in _sys_nic_move() : timeout\n"); 515 672 return -1; 516 673 } 517 674 } 518 kernel_paddr = desc & 0x0000FFFFFFFFFFFFULL; 675 676 // compute kernel buffer physical address 677 kernel_buffer_paddr = kernel_buffer_desc & 0x0000FFFFFFFFFFFFULL; 519 678 520 // move one container using, a physical_memcpy 521 if ( is_rx ) _physical_memcpy( user_paddr, 522 kernel_paddr, 523 GIET_NIC_CHBUF_SIZE ); 524 525 else _physical_memcpy( kernel_paddr, 526 user_paddr, 527 GIET_NIC_CHBUF_SIZE ); 528 529 // update chbuf status and index 530 if ( is_rx ) chbuf->buffer[index] = desc & 0x0000FFFFFFFFFFFFULL; 531 else chbuf->buffer[index] = desc | 0x8000000000000000ULL; 532 if ( index == (GIET_NIC_CHBUF_NBUFS - 1) ) chbuf->index = 0; 533 else chbuf->index = index + 1; 679 // move one container, using a physical_memcpy 680 // We must maintain L2/L3 cache coherence 681 if ( is_rx ) 682 { 683 // inval kernel buffer in L2 before read in L2 684 _mmc_inval( kernel_buffer_paddr, GIET_NIC_BUFSIZE ); 685 686 // transfer data from kernel buffer to user buffer 687 _physical_memcpy( user_buffer_paddr, 688 kernel_buffer_paddr, 689 GIET_NIC_BUFSIZE ); 690 691 } 692 else 693 { 694 // transfer data from user buffer to kernel buffer 695 _physical_memcpy( kernel_buffer_paddr, 696 user_buffer_paddr, 697 GIET_NIC_BUFSIZE ); 698 699 // sync kernel buffer in L2 after write in L2 700 _mmc_sync( kernel_buffer_paddr, GIET_NIC_BUFSIZE ); 701 } 702 703 // update kernel chbuf status and index 704 if ( is_rx ) chbuf->buffer[index] = kernel_buffer_paddr & 0x0000FFFFFFFFFFFFULL; 705 else chbuf->buffer[index] = kernel_buffer_paddr | 0x8000000000000000ULL; 706 707 if ( index == (GIET_NIC_NBUFS - 1) ) chbuf->index = 0; 708 else chbuf->index = index + 1; 709 710 // sync kernel chbuf in L2 after write in L2 711 _mmc_sync( kernel_chbuf_paddr, sizeof( nic_chbuf_t ) ); 712 713 // release the lock protecting the chbuf 714 _lock_release( lock ); 715 716 #if GIET_DEBUG_NIC 717 _printf("\n[GIET DEBUG NIC] Task %d of vspace %d exit _sys_nic_move()\n", 718 thread, vspace ); 719 #endif 534 720 535 721 return 0; … … 571 757 _cma_channel_stop( cma_channel ); 572 758 759 return 0; 760 } 761 762 //////////////////////////////////////// 763 int _sys_nic_clear( unsigned int is_rx ) 764 { 765 unsigned int nic_channel; 766 767 // get NIC channel 768 if ( is_rx ) nic_channel = _get_context_slot( CTX_NIC_RX_ID ); 769 else nic_channel = _get_context_slot( CTX_NIC_TX_ID ); 770 771 if ( nic_channel >= NB_NIC_CHANNELS ) 772 { 773 _printf("\n[GIET_ERROR] in _sys_nic_start(): NIC channel not allocated\n"); 774 return -1; 775 } 776 777 if ( is_rx ) 778 { 779 _nic_set_global_register( NIC_G_NPKT_RX_G2S_RECEIVED , 0 ); 780 _nic_set_global_register( NIC_G_NPKT_RX_DES_TOO_SMALL , 0 ); 781 _nic_set_global_register( NIC_G_NPKT_RX_DES_TOO_BIG , 0 ); 782 _nic_set_global_register( NIC_G_NPKT_RX_DES_MFIFO_FULL , 0 ); 783 _nic_set_global_register( NIC_G_NPKT_RX_DES_CRC_FAIL , 0 ); 784 _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_RECEIVED , 0 ); 785 _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_BROADCAST , 0 ); 786 _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_DST_FAIL , 0 ); 787 _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_CH_FULL , 0 ); 788 } 789 else 790 { 791 _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_RECEIVED , 0 ); 792 _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_TRANSMIT , 0 ); 793 _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_BIG , 0 ); 794 _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_SMALL , 0 ); 795 _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_SRC_FAIL , 0 ); 796 _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_BYPASS , 0 ); 797 _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_BROADCAST , 0 ); 798 } 799 return 0; 800 } 801 802 //////////////////////////////////////// 803 int _sys_nic_stats( unsigned int is_rx ) 804 { 805 unsigned int nic_channel; 806 807 // get NIC channel 808 if ( is_rx ) nic_channel = _get_context_slot( CTX_NIC_RX_ID ); 809 else nic_channel = _get_context_slot( CTX_NIC_TX_ID ); 810 811 if ( nic_channel >= NB_NIC_CHANNELS ) 812 { 813 _printf("\n[GIET_ERROR] in _sys_nic_start(): NIC channel not allocated\n"); 814 return -1; 815 } 816 817 if ( is_rx ) 818 { 819 unsigned int received = _nic_get_global_register( NIC_G_NPKT_RX_G2S_RECEIVED ); 820 unsigned int too_small = _nic_get_global_register( NIC_G_NPKT_RX_DES_TOO_SMALL ); 821 unsigned int too_big = _nic_get_global_register( NIC_G_NPKT_RX_DES_TOO_BIG ); 822 unsigned int fifo_full = _nic_get_global_register( NIC_G_NPKT_RX_DES_MFIFO_FULL ); 823 unsigned int crc_fail = _nic_get_global_register( NIC_G_NPKT_RX_DES_CRC_FAIL ); 824 unsigned int transmit = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_RECEIVED ); 825 unsigned int broadcast = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_BROADCAST ); 826 unsigned int dst_fail = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_DST_FAIL ); 827 unsigned int ch_full = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_CH_FULL ); 828 829 _printf("\n### Network Controller RX Statistics ###\n" 830 "- packets received : %d\n" 831 "- packets transmit : %d\n" 832 "- too small : %d\n" 833 "- too big : %d\n" 834 "- fifo full : %d\n" 835 "- crc fail : %d\n" 836 "- dst mac fail : %d\n" 837 "- channel full : %d\n" 838 "- broadcast : %d\n", 839 received, 840 transmit, 841 too_small, 842 too_big, 843 fifo_full, 844 crc_fail, 845 dst_fail, 846 ch_full, 847 broadcast ); 848 } 849 else 850 { 851 unsigned int received = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_RECEIVED ); 852 unsigned int transmit = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_TRANSMIT ); 853 unsigned int too_big = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_BIG ); 854 unsigned int too_small = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_SMALL ); 855 unsigned int src_fail = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_SRC_FAIL ); 856 unsigned int bypass = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_BYPASS ); 857 unsigned int broadcast = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_BROADCAST ); 858 859 _printf("\n### Network Controller TX Statistics ###\n" 860 "- packets received : %d\n" 861 "- packets transmit : %d\n" 862 "- too small : %d\n" 863 "- too big : %d\n" 864 "- src mac fail : %d\n" 865 "- bypass : %d\n" 866 "- broadcast : %d\n", 867 received, 868 transmit, 869 too_big, 870 too_small, 871 src_fail, 872 bypass, 873 broadcast ); 874 } 573 875 return 0; 574 876 } … … 612 914 { 613 915 // get a new CMA channel index 614 unsigned int channel = _atomic_increment( &_cma_channel_allocator );916 unsigned int channel = _atomic_increment( &_cma_channel_allocator, 1 ); 615 917 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 616 918 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); -
soft/giet_vm/giet_kernel/sys_handler.h
r449 r459 13 13 #define _SYS_HANDLER_H 14 14 15 #include <mapping_info.h> 16 #include <giet_config.h> 15 #include "giet_config.h" 16 #include "locks.h" 17 18 #if !defined ( GIET_NIC_NBUFS ) 19 # error: You must define GIET_NIC_NBUFS in the giet_config.h file 20 #endif 21 22 #if !defined ( GIET_NIC_NFAKE ) 23 # error: You must define GIET_NIC_NFAKE in the giet_config.h file 24 #endif 25 26 #if !defined ( GIET_NIC_BUFSIZE ) 27 # error: You must define GIET_NIC_BUFSIZE in the giet_config.h file 28 #endif 29 30 #if !defined ( GIET_NIC_TIMEOUT ) 31 # error: You must define GIET_NIC_TIMEOUT in the giet_config.h file 32 #endif 33 34 #if !defined ( GIET_NIC_MAC4 ) 35 # error: You must define GIET_NIC_MAC4 in the giet_config.h file 36 #endif 37 38 #if !defined ( GIET_NIC_MAC2 ) 39 # error: You must define GIET_NIC_MAC2 in the giet_config.h file 40 #endif 41 42 #if ( (GIET_NIC_NBUFS + GIET_NIC_NFAKE) % 8 ) 43 #error: GIET_NIC_NBUFS + GIET_NIC_NFAKE must be multiple of 8 for alignment 44 #endif 17 45 18 46 /////////////////////////////////////////////////////////////////////////////////// … … 23 51 24 52 /////////////////////////////////////////////////////////////////////////////////// 25 // This structure is used by the vci_chbuf_dma component to transfera stream53 // This structure is used by the CMA component to move a stream 26 54 // of images from two buffers in user space to the frame buffer in kernel space. 27 // It contains two chbuf descriptors 55 // it must be 64 bytes aligned. 56 // It contains two chbuf arrays: 28 57 // - The SRC chbuf contains two buffers (buf0 & buf1), that can be in user space. 29 58 // - The DST cbuf contains one single buffer (fbf), that is the frame buffer. 59 // - The length field define the buffer size (bytes) 30 60 /////////////////////////////////////////////////////////////////////////////////// 31 61 32 62 typedef struct fbf_chbuf_s 33 63 { 34 unsigned long long buf0; // physical address + status for user buffer 035 unsigned long long buf1; // physical address + status for user buffer 136 unsigned long long fbf; // physical address + status for user buffer 037 unsigned int length; // buffer length (bytes)38 unsigned int padding ; // 8bytes alignment64 unsigned long long buf0; // physical address + status for user buffer 0 65 unsigned long long buf1; // physical address + status for user buffer 1 66 unsigned long long fbf; // physical address + status for user buffer 0 67 unsigned int length; // buffer length (bytes) 68 unsigned int padding[9]; // 64 bytes alignment 39 69 } fbf_chbuf_t; 40 70 41 71 ////////////////////////////////////////////////////////////////////////////////// 42 // This structure define the generic chained buffer used by the vci_chbuf_dma 43 // component to move a stream of containers to or from the vci_multi_nic component. 72 // This structure is used by the CMA component to move a stream 73 // of packet containers between the NIC component an a chbuf containing 74 // a variable number of buffers in kernel space. 44 75 // The same structure is used for both TX or RX transfers. 76 // It must be 64 bytes aligned. 45 77 // The single buffer size and the number of buffers must be defined by the 46 // GIET_NIC_CHBUF_SIZE and GIET_NIC_CHBUF_NBUFS parameters in giet_config.h. 47 // - The buffer array is the chbuf descriptor, shared by the vci_chbuf_dma, 48 // and by the kernel. 49 // - The index field is only used by the kernel. It define the currently pointed 78 // GIET_NIC_BUFSIZE and GIET_NIC_NBUFS parameters in giet_config.h. 79 // - The buffer array implements the chbuf, and is concurently accessed 80 // by the CMA component and by the kernel code. 81 // - The lock must be taken by the kernel code, because several user tasks 82 // can concurently try to consume buffers in the chbuf. 83 // - The index is only used by the kernel, and define the currently pointed 50 84 // buffer for read (RX transfer) or write (TX transfer). 51 85 ////////////////////////////////////////////////////////////////////////////////// … … 53 87 typedef struct nic_chbuf_s 54 88 { 55 unsigned long long buffer[GIET_NIC_CHBUF_NBUFS]; // chbuf descriptor 56 unsigned int index; // current buffer index 57 unsigned int padding; // 8 bytes alignment 89 unsigned long long buffer[GIET_NIC_NBUFS]; // Kernel CHBUF 90 unsigned long long unused[GIET_NIC_NFAKE]; // padding for 64 bytes alignment 91 unsigned int index; // current buffer index 92 unsigned int padding[15]; // padding for 64 bytes alignment 58 93 } nic_chbuf_t; 59 94 … … 95 130 int _sys_nic_alloc( unsigned int is_rx ); 96 131 97 int _sys_nic_start( unsigned int is_rx, 98 unsigned int mac4, 99 unsigned int mac2 ); 132 int _sys_nic_start( unsigned int is_rx ); 100 133 101 134 int _sys_nic_move( unsigned int is_rx, 135 unsigned int nic_channel, 102 136 void* buffer ); 103 137 104 138 int _sys_nic_stop( unsigned int is_rx ); 139 140 int _sys_nic_clear( unsigned int is_rx ); 141 142 int _sys_nic_stats( unsigned int is_rx ); 105 143 106 144 //////////////////////////////////////////////////////////////////////////////
Note: See TracChangeset
for help on using the changeset viewer.