Changeset 629 for trunk/softs/giet_tsar/stdio.c
- Timestamp:
- Feb 12, 2014, 9:51:23 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/softs/giet_tsar/stdio.c
r626 r629 4 4 // Date : janvier 2014 5 5 // 6 // This file define varions functions that can be used by applications to access6 // This file defines various functions that can be used by applications to access 7 7 // peripherals, for the TSAR multi-processors multi_clusters architecture. 8 8 // There is NO separation between application code and system code, as the … … 22 22 // - NB_PROCS_MAX : max number of processor per cluster 23 23 // - NB_TTY_CHANNELS : max number of TTY channels 24 // - USE_EXT_IO : use external peripherals if not zero 24 25 // 25 26 // The follobing base addresses must be defined in the ldscript … … 31 32 #include "stdio.h" 32 33 34 #if !defined(NB_PROCS_MAX) 35 #error: you must define NB_PROCS_MAX in the hard_config.h file 36 #endif 37 38 #if !defined(USE_EXT_IO) 39 #error: you must define USE_EXT_IO in the hard_config.h file 40 #endif 41 42 #if !defined(X_SIZE) 43 #error: you must define X_SIZE in the hard_config.h file 44 #endif 45 46 #if !defined(Y_SIZE) 47 #error: you must define Y_SIZE in the hard_config.h file 48 #endif 49 50 #if !defined(X_WIDTH) 51 #error: you must define X_WIDTH in the hard_config.h file 52 #endif 53 54 #if (X_WIDTH != 4) 55 #error: The X_WIDTH parameter must be equal to 4 56 #endif 57 58 #if !defined(Y_WIDTH) 59 #error: you must define X_WIDTH in the hard_config.h file 60 #endif 61 62 #if (X_WIDTH != 4) 63 #error: The Y_WIDTH parameter must be equal to 4 64 #endif 65 66 #if !defined(NB_TTY_CHANNELS) 67 #error: you must define NB_TTY_CHANNELS in the hard_config.h file 68 #endif 69 70 71 72 33 73 #define NB_LOCKS 256 34 74 #define NB_BARRIERS 16 … … 74 114 75 115 //////////////////////////////////////////////////////////////////////////////////////// 76 // Taken from MutekH.116 // Memcopy taken from MutekH. 77 117 //////////////////////////////////////////////////////////////////////////////////////// 78 118 in_drivers void* _memcpy( void* _dst, … … 100 140 return _dst; 101 141 } 102 142 //////////////////////////////////////////////////////////////////////////////////////// 143 // Memcopy using extended addresses 144 //////////////////////////////////////////////////////////////////////////////////////// 145 in_drivers void _extended_memcpy( unsigned int dst_cluster, 146 unsigned int dst_address, 147 unsigned int src_cluster, 148 unsigned int src_address, 149 unsigned int length ) 150 { 151 if ( (dst_address & 0x3) || (src_address & 0x3) || (length & 0x3) ) 152 { 153 _tty_get_lock( 0 ); 154 _tty_puts( "ERROR in _extended_memcpy()" ); 155 _tty_release_lock( 0 ); 156 _exit(); 157 } 158 159 unsigned int i; 160 unsigned int word; 161 162 for ( i = 0 ; i < length ; i = i+4 ) 163 { 164 word = _word_extended_read( src_cluster, (src_address + i) ); 165 _word_extended_write( dst_cluster, (dst_address + i), word ); 166 } 167 } 103 168 //////////////////////////////////////////////////////////////////////////////////////// 104 169 // Access CP0 and returns processor ident … … 179 244 } 180 245 181 /////////////////////////////////////////////////////////////////////////////////////// 182 // Exit (suicide) after printing message on a TTY terminal. 246 //////////////////////////////////////////////////////////////////////////// 247 // This function makes a physical read access to a 32 bits word in memory, 248 // after a temporary paddr extension. 249 //////////////////////////////////////////////////////////////////////////// 250 in_drivers unsigned int _word_extended_read( unsigned int cluster, 251 unsigned int address ) 252 { 253 unsigned int value; 254 asm volatile( 255 "li $3, 0xFFFFFFFE \n" 256 "mfc0 $2, $12 \n" 257 "and $3, $2, $3 \n" 258 "mtc0 $3, $12 \n" /* IRQ disabled */ 259 260 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 261 "lw %0, 0(%1) \n" /* value <= *paddr */ 262 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 263 264 "li $3, 0x00000001 \n" 265 "mfc0 $2, $12 \n" 266 "or $3, $3, $2 \n" 267 "mtc0 $3, $12 \n" /* IRQ enabled */ 268 : "=r" (value) 269 : "r" (address), "r" (cluster) 270 : "$2", "$3" ); 271 return value; 272 } 273 //////////////////////////////////////////////////////////////////////////// 274 // This function makes a physical read access to a single byte in memory, 275 // after a temporary paddr extension. 276 //////////////////////////////////////////////////////////////////////////// 277 in_drivers unsigned char _byte_extended_read( unsigned int cluster, 278 unsigned int address ) 279 { 280 unsigned int value; 281 asm volatile( 282 "li $3, 0xFFFFFFFE \n" 283 "mfc0 $2, $12 \n" 284 "and $3, $2, $3 \n" 285 "mtc0 $3, $12 \n" /* IRQ disabled */ 286 287 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 288 "lb %0, 0(%1) \n" /* value <= *paddr */ 289 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 290 291 "li $3, 0x00000001 \n" 292 "mfc0 $2, $12 \n" 293 "or $3, $3, $2 \n" 294 "mtc0 $3, $12 \n" /* IRQ enabled */ 295 : "=r" (value) 296 : "r" (address), "r" (cluster) 297 : "$2", "$3" ); 298 return (unsigned char)value; 299 } 300 //////////////////////////////////////////////////////////////////////////// 301 // This function makes a physical write access to a 32 bits word in memory, 302 // after a temporary DTLB address extension. 303 //////////////////////////////////////////////////////////////////////////// 304 in_drivers void _word_extended_write( unsigned int cluster, 305 unsigned int address, 306 unsigned int word ) 307 { 308 asm volatile( 309 "li $3, 0xFFFFFFFE \n" 310 "mfc0 $2, $12 \n" 311 "and $3, $2, $3 \n" 312 "mtc0 $3, $12 \n" /* IRQ disabled */ 313 314 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 315 "sw %0, 0(%1) \n" /* *paddr <= value */ 316 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 317 318 "li $3, 0x00000001 \n" 319 "mfc0 $2, $12 \n" 320 "or $3, $2, $3 \n" 321 "mtc0 $3, $12 \n" /* IRQ enabled */ 322 : 323 : "r" (word), "r" (address), "r" (cluster) 324 : "$2", "$3"); 325 } 326 //////////////////////////////////////////////////////////////////////////// 327 // This function makes a physical write access to single byte in memory, 328 // after a temporary DTLB de-activation and address extension. 329 //////////////////////////////////////////////////////////////////////////// 330 in_drivers void _byte_extended_write( unsigned int cluster, 331 unsigned int address, 332 unsigned char byte ) 333 { 334 asm volatile( 335 "li $3, 0xFFFFFFFE \n" 336 "mfc0 $2, $12 \n" 337 "and $3, $2, $3 \n" 338 "mtc0 $3, $12 \n" /* IRQ disabled */ 339 340 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 341 "sb %0, 0(%1) \n" /* *paddr <= value */ 342 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 343 344 "li $3, 0x00000001 \n" 345 "mfc0 $2, $12 \n" 346 "or $3, $2, $3 \n" 347 "mtc0 $3, $12 \n" /* IRQ enabled */ 348 : 349 : "r" (byte), "r" (address), "r" (cluster) 350 : "$2", "$3"); 351 } 352 353 /////////////////////////////////////////////////////////////////////////////////////// 354 // Exit (suicide) after printing message on TTY0 183 355 /////////////////////////////////////////////////////////////////////////////////////// 184 356 in_drivers void _exit() … … 189 361 unsigned int y = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1); 190 362 191 _tty_printf("\n\n!!! Exit Processor (%d,%d,%d) !!!\n", x, y, l ); 363 _tty_get_lock( 0 ); 364 _tty_puts("\n !!! exit proc["); 365 _tty_putd( x ); 366 _tty_puts(","); 367 _tty_putd( y ); 368 _tty_puts(","); 369 _tty_putd( l ); 370 _tty_puts("] !!!\n"); 371 _tty_release_lock( 0 ); 192 372 193 373 while(1) asm volatile("nop"); // infinite loop... … … 227 407 /////////////////////////////////////////////////////////////////////////////////////// 228 408 // The total number of TTY terminals is defined by NB_TTY_CHANNELS. 229 // 1. If there is only one terminal, it is supposed to be shared, and used by 230 // all processors: a lock must be taken before display. 231 // 2. If there is several terminals, and the number of processors is smaller 232 // than the number of terminals, there is one terminal per processor, but 233 // the TTY index is not equal to the proc_id, due to cluster indexing policy: 234 // - proc_id = cluster_xy * NB_PROCS_MAX + local_id (with cluster_xy = x << Y_WIDTH + y) 235 // - tty_id = cluster_id * NB_PROCS_MAX + local_id (with cluster_id = x * Y_SIZE + y) 236 // 3. If the computed tty_id is larger than NB_TTY_CHANNELS, an error is returned. 409 // - If there is only one terminal, it is supposed to be shared, and used by 410 // all processors: a lock must be taken before display. 411 // - If there is several terminals, and the number of processors is smaller 412 // than the number of terminals, there is one terminal per processor, but 413 // the TTY index is not equal to the proc_id, due to cluster indexing policy: 414 // proc_id = cluster_xy * NB_PROCS_MAX + local_id (with cluster_xy = x << Y_WIDTH + y) 415 // tty_id = cluster_id * NB_PROCS_MAX + local_id (with cluster_id = x * Y_SIZE + y) 416 // - If the computed tty_id is larger than NB_TTY_CHANNELS, an error is returned. 417 /////////////////////////////////////////////////////////////////////////////////////// 418 // If USE_EXT_IO is set, we use the TTY controler implemented in cluster_io 419 // (x = X_SIZE-1 / y = Y_SIZE), which requires and extended address access. 420 // If USE_EXT_IO not set, we use the single channel TTY contrÃŽler in cluster (0,0). 421 /////////////////////////////////////////////////////////////////////////////////////// 422 237 423 /////////////////////////////////////////////////////////////////////////////////////// 238 424 // Write one or several characters directly from a fixed length user buffer 239 425 // to the TTY_WRITE register of the TTY controler. 426 // The channel index must be checked by the calling function. 240 427 // This is a non blocking call : it test the TTY_STATUS register. 241 428 // If the TTY_STATUS_WRITE bit is set, the transfer stops and the function … … 246 433 unsigned int channel ) 247 434 { 248 char* tty_address; 249 unsigned int base = (unsigned int)&seg_tty_base; 250 unsigned int nwritten = 0; 251 int i; 252 253 tty_address = (char*)(base + channel*TTY_SPAN*4); 435 unsigned int base = (unsigned int)&seg_tty_base + channel*TTY_SPAN*4; 436 unsigned int nwritten = 0; 437 unsigned int cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 438 unsigned int status; 439 unsigned int i; 254 440 255 441 for ( i=0 ; i < length ; i++ ) 256 442 { 257 if((tty_address[TTY_STATUS*4] & 0x2) == 0x2) break; 258 else 259 { 260 tty_address[TTY_WRITE*4] = buffer[i]; // write character 261 nwritten++; 443 if( USE_EXT_IO ) // extended addressing to reach cluster_io 444 { 445 status = _word_extended_read( cluster_io, base + TTY_STATUS*4 ); 446 if ( (status & 0x2) == 0x2 ) break; 447 else 448 { 449 _byte_extended_write( cluster_io, base + TTY_WRITE*4 , buffer[i] ); 450 nwritten++; 451 } 452 } 453 else // direct addressing to cluster(0,0) 454 { 455 char* tty = (char*)base; 456 if ( (tty[TTY_STATUS*4] & 0x2) == 0x2 ) break; 457 else 458 { 459 tty[TTY_WRITE*4] = buffer[i]; // write character 460 nwritten++; 461 } 262 462 } 263 463 } … … 265 465 return nwritten; 266 466 } 467 267 468 /////////////////////////////////////////////////////////////////////////////////////// 268 469 // Fetch one character directly from the TTY_READ register of the TTY controler, 269 470 // and writes this character to the user buffer. 471 // The channel index must be checked by the calling function. 270 472 // This is a non blocking call : it returns 0 if the register is empty, 271 473 // and returns 1 if the register is full. … … 274 476 unsigned int channel ) 275 477 { 276 char* tty_address; 277 unsigned int base = (unsigned int)&seg_tty_base; 278 279 tty_address = (char*)(base + channel*TTY_SPAN*4); 280 281 if((tty_address[TTY_STATUS*4] & 0x1) == 0x1) 282 { 283 buffer[0] = tty_address[TTY_READ*4]; 284 return 1; 478 unsigned int base = (unsigned int)&seg_tty_base + channel*TTY_SPAN*4; 479 unsigned int cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 480 unsigned int status; 481 482 if( USE_EXT_IO ) 483 { 484 status = _word_extended_read( cluster_io, base + TTY_STATUS*4 ); 485 if ( (status & 0x1) == 0x1 ) 486 { 487 buffer[0] = (char)_word_extended_read( cluster_io, base + TTY_READ*4 ); 488 return 1; 489 } 490 else 491 { 492 return 0; 493 } 285 494 } 286 495 else 287 496 { 288 return 0; 289 } 290 } 497 char* tty = (char*)base; 498 499 if((tty[TTY_STATUS*4] & 0x1) == 0x1) 500 { 501 buffer[0] = tty[TTY_READ*4]; 502 return 1; 503 } 504 else 505 { 506 return 0; 507 } 508 } 509 } 510 291 511 ////////////////////////////////////////////////////////////////////////////// 292 512 // This function displays a string on TTY0. … … 356 576 in_drivers void _tty_get_lock( unsigned int channel ) 357 577 { 358 unsigned int* tty_address = (unsigned int *) &seg_tty_base; 359 while ( tty_address[channel * TTY_SPAN + TTY_CONFIG] ) asm volatile("nop"); 578 if ( USE_EXT_IO ) // extended addressing to cluster_io 579 { 580 unsigned int cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 581 unsigned int address = (unsigned int)&seg_tty_base 582 + ((TTY_CONFIG + channel*TTY_SPAN)*4); 583 while ( _word_extended_read( cluster_io, address ) ) asm volatile("nop"); 584 } 585 else // direct addressing to cluster(0,0) 586 { 587 unsigned int* tty = (unsigned int *) &seg_tty_base; 588 while ( tty[channel * TTY_SPAN + TTY_CONFIG] ) asm volatile("nop"); 589 } 360 590 } 361 591 … … 366 596 in_drivers void _tty_release_lock( unsigned int channel ) 367 597 { 368 unsigned int* tty_address = (unsigned int *) &seg_tty_base; 369 tty_address[channel * TTY_SPAN + TTY_CONFIG] = 0; 598 if ( USE_EXT_IO ) // extended addressing to cluster_io 599 { 600 unsigned int cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 601 unsigned int address = (unsigned int)&seg_tty_base 602 + ((TTY_CONFIG + channel*TTY_SPAN)*4); 603 _word_extended_write( cluster_io, address, 0 ); 604 } 605 else // direct addressing to cluster(0,0) 606 { 607 unsigned int* tty_address = (unsigned int *) &seg_tty_base; 608 tty_address[channel * TTY_SPAN + TTY_CONFIG] = 0; 609 } 370 610 } 371 611 … … 383 623 unsigned int y; 384 624 385 // compute TTY terminal index 386 if ( NB_TTY_CHANNELS == 1 ) 387 { 388 channel = 0; 389 } 390 else 391 { 392 l = (proc_id % NB_PROCS_MAX); 393 x = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 394 y = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1); 395 channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l; 396 if (channel >= NB_TTY_CHANNELS ) 397 { 398 _tty_get_lock( 0 ); 399 _tty_puts( "ERROR in _tty_getc()\n" ); 400 _tty_release_lock( 0 ); 401 _exit(); 402 } 625 // check TTY channel 626 l = (proc_id % NB_PROCS_MAX); 627 x = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 628 y = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1); 629 channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l; 630 if (channel >= NB_TTY_CHANNELS ) 631 { 632 _tty_get_lock( 0 ); 633 _tty_puts( "ERROR in _tty_getc(): TTY index too large\n" ); 634 _tty_release_lock( 0 ); 635 _exit(); 403 636 } 404 637 … … 433 666 unsigned int i; 434 667 unsigned int channel; 435 unsigned int l;436 668 unsigned int x; 437 669 unsigned int y; 438 439 // compute TTY terminal index 440 if ( NB_TTY_CHANNELS == 1 ) 441 { 442 channel = 0; 443 } 444 else 445 { 446 l = (proc_id % NB_PROCS_MAX); 447 x = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 448 y = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1); 449 channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l; 450 if (channel >= NB_TTY_CHANNELS ) 451 { 452 _tty_get_lock( 0 ); 453 _tty_puts( "ERROR in _tty_getw()\n" ); 454 _tty_release_lock( 0 ); 455 _exit(); 456 } 670 unsigned int l; 671 672 // check TTY channel 673 l = (proc_id % NB_PROCS_MAX); 674 x = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 675 y = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1); 676 channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l; 677 if (channel >= NB_TTY_CHANNELS ) 678 { 679 _tty_get_lock( 0 ); 680 _tty_puts( "ERROR in _tty_getw(): TTY index too large\n" ); 681 _tty_release_lock( 0 ); 682 _exit(); 457 683 } 458 684 … … 519 745 520 746 unsigned int channel; 521 unsigned int l;522 747 unsigned int x; 523 748 unsigned int y; 524 749 unsigned int proc_id = _procid(); 525 750 526 // compute TTY channel 527 if ( NB_TTY_CHANNELS == 1 ) 751 // compute TTY channel : 752 // if the number of TTY channels is smaller 753 // than the number of clusters, use TTY_0_0 754 // else, TTY channel <= cluster index 755 if ( NB_TTY_CHANNELS < (X_SIZE * Y_SIZE) ) 528 756 { 529 757 channel = 0; … … 531 759 else 532 760 { 533 l = (proc_id % NB_PROCS_MAX);534 761 x = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 535 762 y = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1); 536 channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l; 537 if (channel >= NB_TTY_CHANNELS ) 538 { 539 _tty_get_lock( 0 ); 540 _tty_puts("ERROR in _tty_printf() for proc[" ); 541 _tty_putd( x ); 542 _tty_puts(","); 543 _tty_putd( y ); 544 _tty_puts(","); 545 _tty_putd( l ); 546 _tty_puts("] / TTY channel too large = "); 547 _tty_putd( channel ); 548 _tty_puts("\n"); 549 _tty_release_lock( 0 ); 550 _exit(); 551 } 763 channel = (x * Y_SIZE + y); 552 764 } 553 765 … … 640 852 ////////////////////////////////////////////////////////////////////////////////////// 641 853 // These functions are the ISRs that must be executed when an IRQ is activated 642 // by the TTY: _tty_isr_X is associated to channel [X].643 // It save the character in the communication buffer _tty_get_buf[X ],644 // and set the set/reset variable _tty_get_full[X ].854 // by the TTY: _tty_isr_XX is associated to TTY channel [XX]. 855 // It save the character in the communication buffer _tty_get_buf[XX], 856 // and set the set/reset variable _tty_get_full[XX]. 645 857 // A character is lost if the buffer is full when the ISR is executed. 646 858 ////////////////////////////////////////////////////////////////////////////////////// 647 859 in_drivers void _tty_isr_indexed(size_t index) 648 860 { 649 char* base = (char*)&seg_tty_base; 650 char* tty_address = (char*)(base + index*TTY_SPAN*4); 651 652 _tty_get_buf[index] = tty_address[TTY_READ*4]; // save character and reset IRQ 653 _tty_get_full[index] = 1; // signals character available 654 } 861 if ( USE_EXT_IO ) // extended addressing to TTY in cluster_io 862 { 863 unsigned int cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 864 unsigned int base = (unsigned int)&seg_tty_base + 865 ((index*TTY_SPAN + TTY_READ)*4); 866 867 _tty_get_buf[index] = (char)_word_extended_read( cluster, base ); 868 } 869 else // direct addressing to TTY in cluster(0,0) 870 { 871 char* tty = (char*)&seg_tty_base + index*TTY_SPAN*4; 872 873 _tty_get_buf[index] = tty[TTY_READ*4]; // save character and reset IRQ 874 } 875 _tty_get_full[index] = 1; // signals character available 876 } 877 878 in_drivers void _tty_isr() { _tty_isr_indexed(0); } 655 879 656 880 in_drivers void _tty_isr_00() { _tty_isr_indexed(0); } … … 689 913 690 914 ////////////////////////////////////////////////////////////////////////////////////////// 691 // I/O BLOCK_DEVICE 692 // The three functions below use the three variables _ioc_lock _ioc_done, 915 // BLOCK_DEVICE (IOC) 916 ////////////////////////////////////////////////////////////////////////////////////////// 917 // The functions below use the three variables _ioc_lock _ioc_done, 693 918 // and _ioc_status for synchronisation. 694 919 // - As the IOC component can be used by several programs running in parallel, … … 705 930 // reset the _ioc_done variable to zero, and releases the _ioc_lock variable. 706 931 /////////////////////////////////////////////////////////////////////////////////////// 932 // If USE_EXT_IO is set, we use the IOC controler implemented in cluster_io 933 // (x = X_SIZE-1 / y = Y_SIZE), which requires and extended address access. 934 // If USE_EXT_IO not set, we use the IOC contrÃŽler in cluster (0,0). 935 /////////////////////////////////////////////////////////////////////////////////////// 936 937 /////////////////////////////////////////////////////////////////////////////////////// 707 938 // This blocking function is used by the _ioc_read() and _ioc_write() functions 708 939 // to get _ioc_lock using LL/SC. … … 720 951 ::"r"(plock):"$2","$3"); 721 952 } 953 722 954 ////////////////////////////////////////////////////////////////////////////////////// 723 955 // Transfer data from a memory buffer to the block_device. … … 725 957 // - buffer : base address of the memory buffer 726 958 // - count : number of blocks to be transfered 727 // The source buffer must be in user address space.959 // - ext : cluster index for the memory buffer 728 960 /////////////////////////////////////////////////////////////////////////////////////// 729 961 in_drivers void _ioc_write( size_t lba, … … 732 964 size_t ext ) 733 965 { 734 volatile unsigned int* ioc_address = (unsigned int*)&seg_ioc_base;735 736 966 // get the lock 737 967 _ioc_get_lock(); 738 968 739 // block_device configuration 740 ioc_address[BLOCK_DEVICE_BUFFER] = (unsigned int)buffer; 741 ioc_address[BLOCK_DEVICE_BUFFER_EXT] = ext; 742 ioc_address[BLOCK_DEVICE_COUNT] = count; 743 ioc_address[BLOCK_DEVICE_LBA] = lba; 744 ioc_address[BLOCK_DEVICE_IRQ_ENABLE] = 1; 745 ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE; 746 } 969 if ( USE_EXT_IO ) // extended addressing to cluster_io 970 { 971 unsigned int cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 972 unsigned int base = (unsigned int)&seg_ioc_base; 973 974 _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER*4, (unsigned int)buffer ); 975 _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER_EXT*4, ext ); 976 _word_extended_write( cluster, base + BLOCK_DEVICE_COUNT*4, count ); 977 _word_extended_write( cluster, base + BLOCK_DEVICE_LBA*4, lba ); 978 _word_extended_write( cluster, base + BLOCK_DEVICE_IRQ_ENABLE*4, 1 ); 979 _word_extended_write( cluster, base + BLOCK_DEVICE_OP*4, BLOCK_DEVICE_WRITE ); 980 } 981 else // direct addressing to cluster(0,0) 982 { 983 unsigned int* ioc = (unsigned int*)&seg_ioc_base; 984 985 ioc[BLOCK_DEVICE_BUFFER] = (unsigned int)buffer; 986 ioc[BLOCK_DEVICE_BUFFER_EXT] = ext; 987 ioc[BLOCK_DEVICE_COUNT] = count; 988 ioc[BLOCK_DEVICE_LBA] = lba; 989 ioc[BLOCK_DEVICE_IRQ_ENABLE] = 1; 990 ioc[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE; 991 } 992 } 993 747 994 /////////////////////////////////////////////////////////////////////////////////////// 748 995 // Transfer data from a file on the block device to a memory buffer. … … 750 997 // - buffer : base address of the memory buffer 751 998 // - count : number of blocks to be transfered 752 // The destination buffer must be in user address space. 753 // All cache lines corresponding to the the target buffer must be invalidated 754 // for cache coherence. 999 // - ext : cluster index for the memory buffer 755 1000 /////////////////////////////////////////////////////////////////////////////////////// 756 1001 in_drivers void _ioc_read( size_t lba, … … 759 1004 size_t ext ) 760 1005 { 761 volatile unsigned int* ioc_address = (unsigned int*)&seg_ioc_base;762 763 1006 // get the lock 764 1007 _ioc_get_lock(); 765 1008 766 // block_device configuration 767 ioc_address[BLOCK_DEVICE_BUFFER] = (unsigned int)buffer; 768 ioc_address[BLOCK_DEVICE_BUFFER_EXT] = ext; 769 ioc_address[BLOCK_DEVICE_COUNT] = count; 770 ioc_address[BLOCK_DEVICE_LBA] = lba; 771 ioc_address[BLOCK_DEVICE_IRQ_ENABLE] = 1; 772 ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ; 773 } 1009 if ( USE_EXT_IO ) // extended addressing to cluster_io 1010 { 1011 unsigned int cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 1012 unsigned int base = (unsigned int)&seg_ioc_base; 1013 1014 _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER*4, (unsigned int)buffer ); 1015 _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER_EXT*4, ext ); 1016 _word_extended_write( cluster, base + BLOCK_DEVICE_COUNT*4, count ); 1017 _word_extended_write( cluster, base + BLOCK_DEVICE_LBA*4, lba ); 1018 _word_extended_write( cluster, base + BLOCK_DEVICE_IRQ_ENABLE*4, 1 ); 1019 _word_extended_write( cluster, base + BLOCK_DEVICE_OP*4, BLOCK_DEVICE_READ ); 1020 } 1021 else // direct addressing to cluster(0,0) 1022 { 1023 unsigned int* ioc = (unsigned int*)&seg_ioc_base; 1024 1025 ioc[BLOCK_DEVICE_BUFFER] = (unsigned int)buffer; 1026 ioc[BLOCK_DEVICE_BUFFER_EXT] = ext; 1027 ioc[BLOCK_DEVICE_COUNT] = count; 1028 ioc[BLOCK_DEVICE_LBA] = lba; 1029 ioc[BLOCK_DEVICE_IRQ_ENABLE] = 1; 1030 ioc[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ; 1031 } 1032 } 1033 774 1034 /////////////////////////////////////////////////////////////////////////////////////// 775 1035 // This blocking function cheks completion of an I/O transfer and reports errors. … … 795 1055 } 796 1056 } 1057 797 1058 ////////////////////////////////////////////////////////////////////////////////////// 798 1059 // This ISR must be executed when an IRQ is activated by IOC to signal completion. … … 803 1064 in_drivers void _ioc_isr() 804 1065 { 805 int* ioc_address = (int*)&seg_ioc_base; 1066 if ( USE_EXT_IO ) // extended addressing to cluster_io 1067 { 1068 unsigned int cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 1069 unsigned int base = (unsigned int)&seg_ioc_base; 1070 1071 _ioc_status = _word_extended_read( cluster, base + BLOCK_DEVICE_STATUS*4 ); 1072 } 1073 else // direct addressing to cluster(Ã ,0) 1074 { 1075 unsigned int* ioc = (unsigned int*)&seg_ioc_base; 806 1076 807 _ioc_status = ioc_address[BLOCK_DEVICE_STATUS]; // save status & reset IRQ 808 _ioc_done = 1; // signals completion 1077 _ioc_status = ioc[BLOCK_DEVICE_STATUS]; // save status & reset IRQ 1078 } 1079 _ioc_done = 1; // signals completion 809 1080 } 810 1081 … … 825 1096 ////////////////////////////////////////////////////////////////////////////////////// 826 1097 // FRAME_BUFFER 1098 ////////////////////////////////////////////////////////////////////////////////////// 827 1099 // The _fb_sync_write & _fb_sync_read functions use a memcpy strategy to implement 828 1100 // the transfer between a data buffer and the frame buffer. 829 1101 // They are blocking until completion of the transfer. 830 1102 ////////////////////////////////////////////////////////////////////////////////////// 1103 1104 ////////////////////////////////////////////////////////////////////////////////////// 831 1105 // _fb_sync_write() 832 1106 // Transfer data from an user buffer to the frame_buffer device with a memcpy. 833 // - offset 1107 // - offset : offset (in bytes) in the frame buffer 834 1108 // - buffer : base address of the memory buffer 835 1109 // - length : number of bytes to be transfered 836 ////////////////////////////////////////////////////////////////////////////////////// 837 in_drivers void _fb_sync_write( size_t offset, 838 void* buffer, 839 size_t length, 840 size_t ext ) 841 { 842 volatile char* fb = (char*)(void*)&seg_fbf_base + offset; 843 char* ub = buffer; 844 845 _memcpy( (void*)fb, (void*)ub, length ); 846 } 1110 // - ext : cluster_xy for the user buffer 1111 ////////////////////////////////////////////////////////////////////////////////////// 1112 in_drivers void _fb_sync_write( unsigned int offset, 1113 unsigned int buffer, 1114 unsigned int length, 1115 unsigned int ext ) 1116 { 1117 unsigned int src_address = buffer; 1118 unsigned int src_cluster = ext; 1119 unsigned int dst_address = (unsigned int)&seg_fbf_base + offset; 1120 unsigned int dst_cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; // cluster_xy for I/O 1121 1122 _extended_memcpy( dst_cluster, 1123 dst_address, 1124 src_cluster, 1125 src_address, 1126 length ); 1127 } 1128 847 1129 /////////////////////////////////////////////////////////////////////////////////////// 848 1130 // _fb_sync_read() 849 1131 // Transfer data from the frame_buffer device to an user buffer with a memcpy. 850 // - offset 1132 // - offset : offset (in bytes) in the frame buffer 851 1133 // - buffer : base address of the memory buffer 852 1134 // - length : number of bytes to be transfered 853 ////////////////////////////////////////////////////////////////////////////////////// 854 in_drivers void _fb_sync_read( size_t offset, 855 void* buffer, 856 size_t length, 857 size_t ext ) 858 { 859 volatile char* fb = (char*)(void*)&seg_fbf_base + offset; 860 char* ub = buffer; 861 862 _memcpy( (void*)ub, (void*)fb, length ); 1135 // - ext : cluster_xy for the user buffer 1136 ////////////////////////////////////////////////////////////////////////////////////// 1137 in_drivers void _fb_sync_read( unsigned int offset, 1138 unsigned int buffer, 1139 unsigned int length, 1140 unsigned int ext ) 1141 { 1142 unsigned int dst_address = buffer; 1143 unsigned int dst_cluster = ext; 1144 unsigned int src_address = (unsigned int)&seg_fbf_base + offset; 1145 unsigned int src_cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; // cluster_xy for I/O 1146 1147 _extended_memcpy( dst_cluster, 1148 dst_address, 1149 src_cluster, 1150 src_address, 1151 length ); 863 1152 } 864 1153 … … 879 1168 _spin_lock[index] = 0; 880 1169 } 1170 881 1171 /////////////////////////////////////////////////////////////////////////////////////// 882 1172 // Try to take a software spin-lock. … … 954 1244 ::"r"(pinit),"r"(pcount),"r"(plock),"r"(value):"$2","$3"); 955 1245 } 1246 956 1247 ////////////////////////////////////////////////////////////////////////////////////// 957 1248 // This blocking function uses a busy_wait technics (on the barrier_lock value),
Note: See TracChangeset
for help on using the changeset viewer.