Changeset 743 for trunk/softs/giet_tsar/stdio.c
- Timestamp:
- Jul 10, 2014, 11:23:56 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/softs/giet_tsar/stdio.c
r631 r743 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 zero25 24 // 26 25 // The follobing base addresses must be defined in the ldscript … … 36 35 #endif 37 36 38 #if !defined( USE_EXT_IO)39 #error: you must define USE_EXT_IO in the hard_config.h file37 #if !defined(X_IO) || !defined(Y_IO) 38 #error: you must define X_IO and Y_IO in the hard_config.h file 40 39 #endif 41 40 … … 68 67 #endif 69 68 70 71 72 73 69 #define NB_LOCKS 256 74 70 #define NB_BARRIERS 16 … … 82 78 83 79 struct plouf; 84 85 extern struct plouf seg_tty_base; 86 extern struct plouf seg_fbf_base; 87 extern struct plouf seg_ioc_base; 88 extern struct plouf seg_mmc_base; 89 extern struct plouf seg_ramdisk_base; 80 extern volatile struct plouf seg_tty_base; 81 extern volatile struct plouf seg_fbf_base; 82 extern volatile struct plouf seg_ioc_base; 83 extern volatile struct plouf seg_mmc_base; 84 extern volatile struct plouf seg_ramdisk_base; 90 85 91 86 //////////////////////////////////////////////////////////////////////////////////////// … … 93 88 //////////////////////////////////////////////////////////////////////////////////////// 94 89 95 in_unckdata int volatile_ioc_lock = 0;96 in_unckdata int volatile_ioc_done = 0;97 in_unckdata int volatile_ioc_status;98 99 in_unckdata char volatile_tty_get_buf[NB_TTY_CHANNELS];100 in_unckdata int volatile_tty_get_full[NB_TTY_CHANNELS] = { [0 ... NB_TTY_CHANNELS-1] = 0 };90 static in_unckdata int volatile _ioc_lock = 0; 91 static in_unckdata int volatile _ioc_done = 0; 92 static in_unckdata int volatile _ioc_status; 93 94 static in_unckdata char volatile _tty_get_buf[NB_TTY_CHANNELS]; 95 static in_unckdata int volatile _tty_get_full[NB_TTY_CHANNELS] = { [0 ... NB_TTY_CHANNELS-1] = 0 }; 101 96 102 97 //////////////////////////////////////////////////////////////////////////////////////// … … 104 99 //////////////////////////////////////////////////////////////////////////////////////// 105 100 106 in_unckdata int volatile _barrier_value[NB_BARRIERS]= { [0 ... NB_BARRIERS-1] = 0 };107 in_unckdata int volatile _barrier_count[NB_BARRIERS]= { [0 ... NB_BARRIERS-1] = 0 };108 in_unckdata int volatile _barrier_lock[NB_BARRIERS]= { [0 ... NB_BARRIERS-1] = 0 };101 static in_unckdata int volatile _barrier_value[NB_BARRIERS] = { [0 ... NB_BARRIERS-1] = 0 }; 102 static in_unckdata int volatile _barrier_count[NB_BARRIERS] = { [0 ... NB_BARRIERS-1] = 0 }; 103 static in_unckdata int volatile _barrier_lock[NB_BARRIERS] = { [0 ... NB_BARRIERS-1] = 0 }; 109 104 110 105 //////////////////////////////////////////////////////////////////////////////////////// … … 112 107 //////////////////////////////////////////////////////////////////////////////////////// 113 108 114 in_unckdata int volatile _spin_lock[NB_LOCKS] ={ [0 ... NB_LOCKS-1] = 0 };109 static in_unckdata int volatile _spin_lock[NB_LOCKS] = { [0 ... NB_LOCKS-1] = 0 }; 115 110 116 111 //////////////////////////////////////////////////////////////////////////////////////// … … 189 184 // Returns the number of processsors controled by the GIET 190 185 //////////////////////////////////////////////////////////////////////////////////////// 191 in_drivers unsigned int _procnumber()186 in_drivers inline unsigned int _procnumber() 192 187 { 193 188 return (unsigned int)(NB_PROCS_MAX * X_SIZE * Y_SIZE); … … 205 200 } 206 201 //////////////////////////////////////////////////////////////////////////////////////// 202 // Access CP0 and enable IRQs 203 //////////////////////////////////////////////////////////////////////////////////////// 204 in_drivers inline void _it_enable() 205 { 206 asm volatile( 207 "mfc0 $8, $12 \n" 208 "ori $8, $8, 1 \n" 209 "mtc0 $8, $12 \n" 210 ::: "$8"); 211 } 212 //////////////////////////////////////////////////////////////////////////////////////// 207 213 // Access CP0 and mask IRQs 208 214 //////////////////////////////////////////////////////////////////////////////////////// 209 in_drivers void _it_mask() 210 { 211 int tmp; 212 asm volatile("mfc0 %0, $12" : "=r" (tmp) ); 213 asm volatile("ori %0, %0, 1" : "=r" (tmp) ); 214 asm volatile("mtc0 %0, $12" : "=r" (tmp) ); 215 } 216 //////////////////////////////////////////////////////////////////////////////////////// 217 // Access CP0 and enable IRQs 218 //////////////////////////////////////////////////////////////////////////////////////// 219 in_drivers void _it_enable() 220 { 221 int tmp; 222 asm volatile("mfc0 %0, $12" : "=r" (tmp) ); 223 asm volatile("addi %0, %0, -1" : "=r" (tmp) ); 224 asm volatile("mtc0 %0, $12" : "=r" (tmp) ); 225 } 215 in_drivers inline void _it_disable() 216 { 217 asm volatile( 218 "li $9, 0xFFFFFFFE \n" 219 "mfc0 $8, $12 \n" 220 "and $8, $8, $9 \n" 221 "mtc0 $8, $12 \n" 222 ::: "$8","$9"); 223 } 224 225 //////////////////////////////////////////////////////////////////////////////////////// 226 // Access CP0 and mask IRQs 227 //////////////////////////////////////////////////////////////////////////////////////// 228 in_drivers inline void _sr_write(int sr) 229 { 230 asm volatile("mtc0 %0, $12 \n" : /* no outputs */ : "r" (sr)); 231 } 232 233 in_drivers inline int _sr_read() 234 { 235 int ret; 236 asm volatile("mfc0 %0, $12 \n" : "=r" (ret)); 237 return ret; 238 } 239 226 240 ////////////////////////////////////////////////////////////////////// 227 241 // Invalidate all cache lines corresponding to a memory buffer. … … 249 263 // after a temporary paddr extension. 250 264 //////////////////////////////////////////////////////////////////////////// 251 in_drivers unsigned int _word_extended_read( unsigned int cluster, 252 unsigned int address ) 253 { 254 unsigned int value; 265 in_drivers volatile unsigned int _word_extended_read( unsigned int cluster, 266 unsigned int address ) 267 { 268 int sr = _sr_read(); 269 volatile unsigned int value; 255 270 asm volatile( 256 271 "li $3, 0xFFFFFFFE \n" 257 "mfc0 $2, $12 \n" 258 "and $3, $2, $3 \n" 272 "and $3, %3, $3 \n" 259 273 "mtc0 $3, $12 \n" /* IRQ disabled */ 260 274 … … 263 277 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 264 278 265 "li $3, 0x00000001 \n"266 "mfc0 $2, $12 \n"267 "or $3, $3, $2 \n"268 "mtc0 $3, $12 \n" /* IRQ enabled */269 279 : "=r" (value) 270 : "r" (address), "r" (cluster) 271 : "$2", "$3" ); 280 : "r" (address), "r" (cluster), "r" (sr) 281 : "$2", "$3", "memory" ); 282 283 _sr_write(sr); 272 284 return value; 273 285 } … … 276 288 // after a temporary paddr extension. 277 289 //////////////////////////////////////////////////////////////////////////// 278 in_drivers unsigned char _byte_extended_read( unsigned int cluster, 279 unsigned int address ) 280 { 281 unsigned int value; 290 in_drivers volatile unsigned char _byte_extended_read( unsigned int cluster, 291 unsigned int address ) 292 { 293 int sr = _sr_read(); 294 volatile unsigned char value; 282 295 asm volatile( 283 296 "li $3, 0xFFFFFFFE \n" 284 "mfc0 $2, $12 \n" 285 "and $3, $2, $3 \n" 297 "and $3, %3, $3 \n" 286 298 "mtc0 $3, $12 \n" /* IRQ disabled */ 287 299 … … 290 302 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 291 303 292 "li $3, 0x00000001 \n"293 "mfc0 $2, $12 \n"294 "or $3, $3, $2 \n"295 "mtc0 $3, $12 \n" /* IRQ enabled */296 304 : "=r" (value) 297 : "r" (address), "r" (cluster) 298 : "$2", "$3" ); 299 return (unsigned char)value; 305 : "r" (address), "r" (cluster), "r" (sr) 306 : "$2", "$3", "memory" ); 307 308 _sr_write(sr); 309 return value; 300 310 } 301 311 //////////////////////////////////////////////////////////////////////////// … … 307 317 unsigned int word ) 308 318 { 319 int sr = _sr_read(); 309 320 asm volatile( 310 321 "li $3, 0xFFFFFFFE \n" 311 "mfc0 $2, $12 \n" 312 "and $3, $2, $3 \n" 322 "and $3, %3, $3 \n" 313 323 "mtc0 $3, $12 \n" /* IRQ disabled */ 314 324 … … 317 327 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 318 328 319 "li $3, 0x00000001 \n" 320 "mfc0 $2, $12 \n" 321 "or $3, $2, $3 \n" 322 "mtc0 $3, $12 \n" /* IRQ enabled */ 329 "sync \n" 323 330 : 324 : "r" (word), "r" (address), "r" (cluster) 325 : "$2", "$3"); 331 : "r" (word), "r" (address), "r" (cluster), "r" (sr) 332 : "$2", "$3", "memory"); 333 334 _sr_write(sr); 326 335 } 327 336 //////////////////////////////////////////////////////////////////////////// … … 333 342 unsigned char byte ) 334 343 { 344 int sr = _sr_read(); 335 345 asm volatile( 336 346 "li $3, 0xFFFFFFFE \n" 337 "mfc0 $2, $12 \n" 338 "and $3, $2, $3 \n" 347 "and $3, %3, $3 \n" 339 348 "mtc0 $3, $12 \n" /* IRQ disabled */ 340 349 … … 343 352 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 344 353 345 "li $3, 0x00000001 \n" 346 "mfc0 $2, $12 \n" 347 "or $3, $2, $3 \n" 348 "mtc0 $3, $12 \n" /* IRQ enabled */ 354 "sync \n" 349 355 : 350 : "r" (byte), "r" (address), "r" (cluster) 351 : "$2", "$3"); 356 : "r" (byte), "r" (address), "r" (cluster), "r" (sr) 357 : "$2", "$3", "memory"); 358 359 _sr_write(sr); 352 360 } 353 361 … … 417 425 // - If the computed tty_id is larger than NB_TTY_CHANNELS, an error is returned. 418 426 /////////////////////////////////////////////////////////////////////////////////////// 419 // If USE_EXT_IO is set, we use the TTY controler implemented in cluster_io420 // (x = X_SIZE-1 / y = Y_SIZE), which requires and extended address access.421 // If USE_EXT_IO not set, we use the single channel TTY contrÃŽler in cluster (0,0).422 ///////////////////////////////////////////////////////////////////////////////////////423 427 424 428 /////////////////////////////////////////////////////////////////////////////////////// … … 434 438 unsigned int channel ) 435 439 { 436 unsigned int base = (unsigned int)&seg_tty_base + channel*TTY_SPAN*4; 437 unsigned int nwritten = 0; 438 unsigned int cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 440 unsigned int base = (unsigned int)&seg_tty_base + channel*TTY_SPAN*4; 441 unsigned int nwritten = 0; 439 442 unsigned int status; 440 unsigned int 443 unsigned int i; 441 444 442 445 for ( i=0 ; i < length ; i++ ) 443 446 { 444 if( USE_EXT_IO ) // extended addressing to reach cluster_io 447 status = _word_extended_read( CLUSTER_IO, base + TTY_STATUS*4 ); 448 if ( (status & 0x2) == 0x2 ) break; 449 else 445 450 { 446 status = _word_extended_read( cluster_io, base + TTY_STATUS*4 ); 447 if ( (status & 0x2) == 0x2 ) break; 448 else 449 { 450 _byte_extended_write( cluster_io, base + TTY_WRITE*4 , buffer[i] ); 451 nwritten++; 452 } 453 } 454 else // direct addressing to cluster(0,0) 455 { 456 char* tty = (char*)base; 457 if ( (tty[TTY_STATUS*4] & 0x2) == 0x2 ) break; 458 else 459 { 460 tty[TTY_WRITE*4] = buffer[i]; // write character 461 nwritten++; 462 } 451 _byte_extended_write( CLUSTER_IO, base + TTY_WRITE*4 , buffer[i] ); 452 nwritten++; 463 453 } 464 454 } … … 477 467 unsigned int channel ) 478 468 { 479 unsigned int base = (unsigned int)&seg_tty_base + channel*TTY_SPAN*4; 480 unsigned int cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 481 unsigned int status; 482 483 if( USE_EXT_IO ) 484 { 485 status = _word_extended_read( cluster_io, base + TTY_STATUS*4 ); 486 if ( (status & 0x1) == 0x1 ) 487 { 488 buffer[0] = (char)_word_extended_read( cluster_io, base + TTY_READ*4 ); 489 return 1; 490 } 491 else 492 { 493 return 0; 494 } 495 } 496 else 497 { 498 char* tty = (char*)base; 499 500 if((tty[TTY_STATUS*4] & 0x1) == 0x1) 501 { 502 buffer[0] = tty[TTY_READ*4]; 503 return 1; 504 } 505 else 506 { 507 return 0; 508 } 509 } 469 unsigned int base = (unsigned int)&seg_tty_base + channel*TTY_SPAN*4; 470 unsigned int status; 471 472 status = _word_extended_read( CLUSTER_IO, base + TTY_STATUS*4 ); 473 if ( (status & 0x1) == 0x1 ) 474 { 475 buffer[0] = (char)_word_extended_read( CLUSTER_IO, base + TTY_READ*4 ); 476 return 1; 477 } 478 return 0; 510 479 } 511 480 … … 550 519 char buf[11]; 551 520 unsigned int i; 552 unsigned int first ;521 unsigned int first = 0; 553 522 554 523 buf[10] = 0; … … 577 546 in_drivers void _tty_get_lock( unsigned int channel ) 578 547 { 579 if ( USE_EXT_IO ) // extended addressing to cluster_io 580 { 581 unsigned int cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 582 unsigned int address = (unsigned int)&seg_tty_base 583 + ((TTY_CONFIG + channel*TTY_SPAN)*4); 584 while ( _word_extended_read( cluster_io, address ) ) asm volatile("nop"); 585 } 586 else // direct addressing to cluster(0,0) 587 { 588 unsigned int* tty = (unsigned int *) &seg_tty_base; 589 while ( tty[channel * TTY_SPAN + TTY_CONFIG] ) asm volatile("nop"); 590 } 548 unsigned int base = (unsigned int)&seg_tty_base; 549 unsigned int offset = (TTY_CONFIG + channel*TTY_SPAN) << 2; 550 while ( _word_extended_read( CLUSTER_IO, base + offset ) ); 591 551 } 592 552 … … 597 557 in_drivers void _tty_release_lock( unsigned int channel ) 598 558 { 599 if ( USE_EXT_IO ) // extended addressing to cluster_io 600 { 601 unsigned int cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 602 unsigned int address = (unsigned int)&seg_tty_base 603 + ((TTY_CONFIG + channel*TTY_SPAN)*4); 604 _word_extended_write( cluster_io, address, 0 ); 605 } 606 else // direct addressing to cluster(0,0) 607 { 608 unsigned int* tty_address = (unsigned int *) &seg_tty_base; 609 tty_address[channel * TTY_SPAN + TTY_CONFIG] = 0; 610 } 559 unsigned int base = (unsigned int)&seg_tty_base; 560 unsigned int offset = (TTY_CONFIG + channel*TTY_SPAN) << 2; 561 _word_extended_write( CLUSTER_IO, base + offset, 0 ); 611 562 } 612 563 … … 860 811 in_drivers void _tty_isr_indexed(size_t index) 861 812 { 862 if ( USE_EXT_IO ) // extended addressing to TTY in cluster_io 863 { 864 unsigned int cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 865 unsigned int base = (unsigned int)&seg_tty_base + 866 ((index*TTY_SPAN + TTY_READ)*4); 867 868 _tty_get_buf[index] = (char)_word_extended_read( cluster, base ); 869 } 870 else // direct addressing to TTY in cluster(0,0) 871 { 872 char* tty = (char*)&seg_tty_base + index*TTY_SPAN*4; 873 874 _tty_get_buf[index] = tty[TTY_READ*4]; // save character and reset IRQ 875 } 813 unsigned int base = (unsigned int)&seg_tty_base; 814 unsigned int offset = (index*TTY_SPAN + TTY_READ) << 2; 815 816 _tty_get_buf[index] = _byte_extended_read(CLUSTER_IO, base + offset); 876 817 _tty_get_full[index] = 1; // signals character available 877 818 } … … 932 873 // reset the _ioc_done variable to zero, and releases the _ioc_lock variable. 933 874 /////////////////////////////////////////////////////////////////////////////////////// 934 // If USE_EXT_IO is set, we use the IOC controler implemented in cluster_io935 // (x = X_SIZE-1 / y = Y_SIZE), which requires and extended address access.936 // If USE_EXT_IO not set, we use the IOC contrÃŽler in cluster (0,0).937 //938 875 // If USE_RAMDISK is set, we access a "virtual" block device controler implemented 939 876 // as a memory-mapped segment in cluster [0,0] at address seg_ramdisk_base. … … 947 884 in_drivers void _ioc_get_lock() 948 885 { 949 register unsigned int* plock = (unsigned int*)&_ioc_lock; 950 951 asm volatile ("_ioc_llsc: \n" 952 "ll $2, 0(%0) \n" // $2 <= _ioc_lock 953 "bnez $2, _ioc_llsc \n" // retry if busy 954 "li $3, 1 \n" // prepare argument for sc 955 "sc $3, 0(%0) \n" // try to set _ioc_busy 956 "beqz $3, _ioc_llsc \n" // retry if not atomic 957 ::"r"(plock):"$2","$3"); 886 register unsigned int* plock = (unsigned int*)&_ioc_lock; 887 888 asm volatile ( 889 "1: \n" 890 "ll $2, 0(%0) \n" // $2 <= _ioc_lock 891 "bnez $2, 1b \n" // retry if busy 892 "li $3, 1 \n" // prepare argument for sc 893 "sc $3, 0(%0) \n" // try to set _ioc_busy 894 "beqz $3, 1b \n" // retry if not atomic 895 ::"r"(plock) :"$2","$3"); 958 896 } 959 897 … … 988 926 _ioc_status = BLOCK_DEVICE_WRITE_SUCCESS; 989 927 _ioc_done = 1; 990 } 991 else if ( USE_EXT_IO ) // extended addressing to cluster_io 992 { 993 unsigned int cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 994 unsigned int base = (unsigned int)&seg_ioc_base; 995 996 _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER*4, (unsigned int)buffer ); 997 _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER_EXT*4, ext ); 998 _word_extended_write( cluster, base + BLOCK_DEVICE_COUNT*4, count ); 999 _word_extended_write( cluster, base + BLOCK_DEVICE_LBA*4, lba ); 1000 _word_extended_write( cluster, base + BLOCK_DEVICE_IRQ_ENABLE*4, 1 ); 1001 _word_extended_write( cluster, base + BLOCK_DEVICE_OP*4, BLOCK_DEVICE_WRITE ); 1002 } 1003 else // direct addressing to cluster(0,0) 1004 { 1005 unsigned int* ioc = (unsigned int*)&seg_ioc_base; 1006 1007 ioc[BLOCK_DEVICE_BUFFER] = (unsigned int)buffer; 1008 ioc[BLOCK_DEVICE_BUFFER_EXT] = ext; 1009 ioc[BLOCK_DEVICE_COUNT] = count; 1010 ioc[BLOCK_DEVICE_LBA] = lba; 1011 ioc[BLOCK_DEVICE_IRQ_ENABLE] = 1; 1012 ioc[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE; 1013 } 928 929 return; 930 } 931 932 unsigned int base = (unsigned int)&seg_ioc_base; 933 _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_BUFFER*4, (unsigned int)buffer ); 934 _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_BUFFER_EXT*4, ext ); 935 _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_COUNT*4, count ); 936 _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_LBA*4, lba ); 937 _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_IRQ_ENABLE*4, 1 ); 938 _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_OP*4, BLOCK_DEVICE_WRITE ); 1014 939 } 1015 940 … … 1044 969 _ioc_status = BLOCK_DEVICE_READ_SUCCESS; 1045 970 _ioc_done = 1; 1046 } 1047 else if ( USE_EXT_IO ) // extended addressing to cluster_io 1048 { 1049 unsigned int cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 1050 unsigned int base = (unsigned int)&seg_ioc_base; 1051 1052 _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER*4, (unsigned int)buffer ); 1053 _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER_EXT*4, ext ); 1054 _word_extended_write( cluster, base + BLOCK_DEVICE_COUNT*4, count ); 1055 _word_extended_write( cluster, base + BLOCK_DEVICE_LBA*4, lba ); 1056 _word_extended_write( cluster, base + BLOCK_DEVICE_IRQ_ENABLE*4, 1 ); 1057 _word_extended_write( cluster, base + BLOCK_DEVICE_OP*4, BLOCK_DEVICE_READ ); 1058 } 1059 else // direct addressing to cluster(0,0) 1060 { 1061 unsigned int* ioc = (unsigned int*)&seg_ioc_base; 1062 1063 ioc[BLOCK_DEVICE_BUFFER] = (unsigned int)buffer; 1064 ioc[BLOCK_DEVICE_BUFFER_EXT] = ext; 1065 ioc[BLOCK_DEVICE_COUNT] = count; 1066 ioc[BLOCK_DEVICE_LBA] = lba; 1067 ioc[BLOCK_DEVICE_IRQ_ENABLE] = 1; 1068 ioc[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ; 1069 } 971 972 return; 973 } 974 975 const unsigned int base = (unsigned int)&seg_ioc_base; 976 _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_BUFFER*4, (unsigned int)buffer ); 977 _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_BUFFER_EXT*4, ext ); 978 _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_COUNT*4, count ); 979 _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_LBA*4, lba ); 980 _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_IRQ_ENABLE*4, 1 ); 981 _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_OP*4, BLOCK_DEVICE_READ ); 982 } 983 984 in_drivers inline unsigned int _ioc_get_blocksize() { 985 const unsigned int base = (unsigned int)&seg_ioc_base; 986 return _word_extended_read( CLUSTER_IO, base + BLOCK_DEVICE_BLOCK_SIZE*4 ); 1070 987 } 1071 988 … … 1102 1019 in_drivers void _ioc_isr() 1103 1020 { 1104 if ( USE_EXT_IO ) // extended addressing to cluster_io 1105 { 1106 unsigned int cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE; 1107 unsigned int base = (unsigned int)&seg_ioc_base; 1108 1109 _ioc_status = _word_extended_read( cluster, base + BLOCK_DEVICE_STATUS*4 ); 1110 } 1111 else // direct addressing to cluster(Ã ,0) 1112 { 1113 unsigned int* ioc = (unsigned int*)&seg_ioc_base; 1114 1115 _ioc_status = ioc[BLOCK_DEVICE_STATUS]; // save status & reset IRQ 1116 } 1117 _ioc_done = 1; // signals completion 1021 unsigned int base = (unsigned int)&seg_ioc_base; 1022 1023 _ioc_status = _word_extended_read( CLUSTER_IO, base + BLOCK_DEVICE_STATUS*4 ); 1024 _ioc_done = 1; // signals completion 1118 1025 } 1119 1026 … … 1142 1049 unsigned int src_cluster = ext; 1143 1050 unsigned int dst_address = (unsigned int)&seg_fbf_base + offset; 1144 unsigned int dst_cluster = ( (X_SIZE-1)<<Y_WIDTH) + Y_SIZE; // cluster_xy for I/O1051 unsigned int dst_cluster = (X_IO << Y_WIDTH) | Y_IO; // cluster_xy for I/O 1145 1052 1146 1053 _extended_memcpy( dst_cluster, … … 1167 1074 unsigned int dst_cluster = ext; 1168 1075 unsigned int src_address = (unsigned int)&seg_fbf_base + offset; 1169 unsigned int src_cluster = ( (X_SIZE-1)<<Y_WIDTH) + Y_SIZE; // cluster_xy for I/O1076 unsigned int src_cluster = (X_IO << Y_WIDTH) | Y_IO; // cluster_xy for I/O 1170 1077 1171 1078 _extended_memcpy( dst_cluster, … … 1184 1091 in_drivers void _mmc_isr() 1185 1092 { 1186 int* mmc_address = (int*)&seg_mmc_base;1093 //int* mmc_address = (int*)&seg_mmc_base; 1187 1094 unsigned int cluster_xy = _procid() / NB_PROCS_MAX; 1188 1095 … … 1225 1132 1226 1133 register int delay = ((_proctime() +_procid()) & 0xF) << 4; 1227 register int * plock = (int *) &_spin_lock[index]; 1228 1229 asm volatile ("_locks_llsc: 1230 "ll $2, 0(%0) 1231 "bnez $2, _locks_delay 1134 register int * plock = (int *) &_spin_lock[index]; 1135 1136 asm volatile ("_locks_llsc: \n" 1137 "ll $2, 0(%0) \n" // $2 <= _locks_lock 1138 "bnez $2, _locks_delay \n" // random delay if busy 1232 1139 "li $3, 1 \n" // prepare argument for sc 1233 "sc $3, 0(%0) \n"// try to set _locks_busy1140 "sc $3, 0(%0) \n" // try to set _locks_busy 1234 1141 "bnez $3, _locks_ok \n" // exit if atomic 1235 1142 "_locks_delay: \n" … … 1239 1146 "beqz $4, _locks_loop \n" // test end delay 1240 1147 "j _locks_llsc \n" // retry 1241 "_locks_ok: 1148 "_locks_ok: \n" 1242 1149 ::"r"(plock),"r"(delay):"$2","$3","$4"); 1243 1150 } … … 1255 1162 in_drivers void _barrier_init(unsigned int index, unsigned int value) 1256 1163 { 1257 1258 register int* pinit = (int*)&_barrier_value[index]; 1259 register int* pcount = (int*)&_barrier_count[index]; 1260 register int* plock = (int*)&_barrier_lock[index]; 1164 register int* pinit = (int*)&_barrier_value[index]; 1165 register int* pcount = (int*)&_barrier_count[index]; 1166 register int* plock = (int*)&_barrier_lock[index]; 1261 1167 1262 1168 if ( index >= NB_BARRIERS ) … … 1269 1175 1270 1176 // parallel initialisation using atomic instructions LL/SC 1271 asm volatile ("_barrier_init_test: 1272 "ll $2, 0(%0) \n"// read barrier_value1273 "bnez $2, _barrier_init_done 1274 "move $3, %3 1275 "sc $3, 0(%0) \n"// try to write barrier_value1276 "beqz $3, _barrier_init_test 1277 "move $3, %3\n"1278 "sw $3, 0(%1) \n"// barrier_count <= barrier_value1177 asm volatile ("_barrier_init_test: \n" 1178 "ll $2, 0(%0) \n" // read barrier_value 1179 "bnez $2, _barrier_init_done \n" 1180 "move $3, %3 \n" 1181 "sc $3, 0(%0) \n" // try to write barrier_value 1182 "beqz $3, _barrier_init_test \n" 1183 "move $3, %3 \n" 1184 "sw $3, 0(%1) \n" // barrier_count <= barrier_value 1279 1185 "move $3, $0 \n" // 1280 "sw $3, 0(%2) \n"// barrier_lock <= 01281 "_barrier_init_done: 1186 "sw $3, 0(%2) \n" // barrier_lock <= 0 1187 "_barrier_init_done: \n" 1282 1188 ::"r"(pinit),"r"(pcount),"r"(plock),"r"(value):"$2","$3"); 1283 1189 } … … 1295 1201 in_drivers void _barrier_wait(unsigned int index) 1296 1202 { 1297 register int* pcount = (int*)&_barrier_count[index]; 1298 register int count; 1299 1300 int lock = _barrier_lock[index]; 1203 register int* pcount = (int*)&_barrier_count[index]; 1204 register int count; 1205 int lock = _barrier_lock[index]; 1301 1206 1302 1207 if ( index >= NB_BARRIERS ) … … 1311 1216 // input : pointer on _barrier_count[index] 1312 1217 // output : count = _barrier_count[index] (before decrementation) 1313 asm volatile ("_barrier_decrement: 1314 "ll %0, 0(%1) 1315 "addi $3, %0, -1 1316 "sc $3, 0(%1) 1317 "beqz $3, _barrier_decrement 1218 asm volatile ("_barrier_decrement: \n" 1219 "ll %0, 0(%1) \n" 1220 "addi $3, %0, -1 \n" 1221 "sc $3, 0(%1) \n" 1222 "beqz $3, _barrier_decrement \n" 1318 1223 :"=&r"(count) 1319 1224 :"r"(pcount) … … 1323 1228 // and the barrier_lock variable, waking up all other waiting tasks 1324 1229 1325 if ( count == 1 ) 1230 if ( count == 1 ) // last task 1326 1231 { 1327 1232 _barrier_count[index] = _barrier_value[index]; … … 1329 1234 _barrier_lock[index] = (lock == 0) ? 1 : 0; 1330 1235 } 1331 else 1332 { 1333 while ( lock == _barrier_lock[index] ) asm volatile("nop");1236 else // other tasks 1237 { 1238 while ( lock == _barrier_lock[index] ); 1334 1239 } 1335 1240 }
Note: See TracChangeset
for help on using the changeset viewer.