- Timestamp:
- Jul 10, 2014, 11:23:56 AM (10 years ago)
- Location:
- trunk/softs/giet_tsar
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/softs/giet_tsar/giet.S
r629 r743 184 184 /* XCU[cluster_xy] access to get PRIO register value */ 185 185 mtc2 $12, $24 /* set PADDR extension */ 186 lw $15, ($26)/* $15 <= PRIO register value */186 lw $15, 0($26) /* $15 <= PRIO register value */ 187 187 mtc2 $0, $24 /* reset PADDR extension */ 188 188 -
trunk/softs/giet_tsar/reset.S
r633 r743 1 1 /******************************************************************************** 2 * 3 * 4 * 2 * File : reset.S 3 * Author : Alain Greiner 4 * Date : 15/01/2014 5 5 ********************************************************************************* 6 6 * This is a boot code for a generic multi-clusters / multi-processors … … 34 34 * - Each processor initializes the stack pointer ($29) depending on proc_id. 35 35 * - Each processor initializes the CP0 EBASE register 36 * 36 * - Only processor 0 initializes the Interrupt vector. 37 37 * - Only processor 0 initializes the IOPIC component. 38 38 * - Each processor initializes its private XCU mask. 39 * 40 * 39 * - Each processor initializes the Status Register (SR) 40 * - Each processor jumps to the same main address in kernel mode... 41 41 ********************************************************************************/ 42 42 … … 44 44 #include "mips32_registers.h" 45 45 46 46 .section .reset,"ax",@progbits 47 47 48 .externseg_stack_base49 .externseg_xcu_base48 .extern seg_stack_base 49 .extern seg_xcu_base 50 50 .extern seg_pic_base 51 51 .extern seg_kcode_base 52 53 54 52 .extern _interrupt_vector 53 .extern _ioc_isr 54 .extern _mmc_isr 55 55 .extern _tty_isr 56 56 .extern main 57 57 58 .globl reset 59 .entreset60 .align258 .globl reset 59 .ent reset 60 .align 2 61 61 62 62 reset: 63 63 .set noreorder 64 64 65 65 /* each proc computes proc_id, lpid, cluster_xy */ 66 66 mfc0 $26, CP0_PROCID 67 andi $26, $26, 0x3FF 67 andi $26, $26, 0x3FF /* at most 1024 processors */ 68 68 move $10, $26 /* $10 <= proc_id */ 69 69 li $27, NB_PROCS_MAX … … 73 73 74 74 /* each proc initializes stack pointer (64K per processor) */ 75 srl $8, $12, Y_WIDTH /* $8 <= x */ 76 li $9, Y_SIZE 77 mul $8, $8, $9 /* $8 <= x * Y_SIZE */ 78 andi $13, $12, (1<<Y_WIDTH)-1 79 addu $8, $8, $13 /* $8 <= x * Y_SIZE + y */ 80 mul $8, $8, $27 /* $8 <= (x*Y_SIZE+y)*NB_PROCS_MAX */ 81 addu $10, $11, $8 /* $10 <= (x*Y_SIZE+y)*NB_PROCS_MAX + lpid */ 82 75 83 la $27, seg_stack_base 76 addi $26, $10, 1 84 addi $26, $10, 1 /* $26 <= (proc_id + 1) */ 77 85 sll $26, $26, 14 /* $26 <= (proc_id + 1) * 16K */ 78 addu $29, $27, $26 86 addu $29, $27, $26 /* $29 <= seg_stack_base(proc_id) */ 79 87 80 88 /* each proc initializes CP0 EBASE register */ … … 83 91 84 92 /* only proc (0,0,0) initializes interrupt vector for IOC, TTY, MMC */ 85 bne 93 bne $10, $0, reset_xcu 86 94 nop 87 95 … … 96 104 /* only proc (0,0,0) initializes IOPIC : IOPIC_ADDRESS[i] <= &XICU[0].WTI_REG[i] */ 97 105 98 li $26, USE_EXT_IO 99 beq $26, $0, reset_xcu /* IOPIC not initialised if not USE_EXT_IO */ 106 #if USE_IOPIC 100 107 101 108 li $20, X_SIZE … … 120 127 121 128 mtc2 $0, CP2_PADDR_EXT /* CP2_PADDR_EXT <= zero */ 129 130 #endif 122 131 123 132 reset_xcu: … … 140 149 141 150 /* initializes SR register */ 142 li $26, 0x0000FF01143 mtc0 $26, $12 151 li $26, 0x0000FF01 152 mtc0 $26, $12 /* SR <= kernel mode / IRQ enable */ 144 153 145 154 /* jumps to main in kernel mode */ 146 la 155 la $26, main 147 156 jr $26 148 157 nop 149 158 150 .end 159 .end reset 151 160 152 161 .set reorder -
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 } -
trunk/softs/giet_tsar/stdio.h
r629 r743 40 40 typedef unsigned int size_t; 41 41 42 // global variables defined in stdio.c42 // constants 43 43 44 extern int volatile _ioc_lock; 45 extern int volatile _ioc_done; 46 extern int volatile _ioc_status; 47 48 extern char volatile _tty_get_buf[]; 49 extern int volatile _tty_get_full[]; 50 51 extern int volatile _barrier_value[]; 52 extern int volatile _barrier_count[]; 53 extern int volatile _barrier_lock[]; 54 55 extern int volatile _spin_lock[]; 44 #define CLUSTER_IO (((X_IO) << (Y_WIDTH)) | (Y_IO)) 56 45 57 46 // functions defined in stdio.c … … 64 53 unsigned int src_address, 65 54 unsigned int length ); 66 unsigned int _procid(); 67 unsigned int _proctime(); 68 unsigned int _procnumber(); 55 inline unsigned int _procid(); 56 inline unsigned int _proctime(); 57 inline unsigned int _procnumber(); 58 59 inline unsigned int _io_cluster(); 69 60 70 61 unsigned int _rand(); … … 72 63 void _it_mask(); 73 64 void _it_enable(); 65 66 int _sr_read(); 67 void _sr_write(int sr); 74 68 75 69 void _dcache_buf_invalidate( const void* buffer, size_t size ); … … 95 89 void _ioc_write( size_t lba, void* buffer, size_t count, size_t ext ); 96 90 void _ioc_read (size_t lba, void* buffer, size_t count, size_t ext ); 91 unsigned int _ioc_get_blocksize(); 97 92 void _ioc_completed(); 98 93 void _ioc_isr(); … … 115 110 void _barrier_wait(size_t index); 116 111 117 unsigned char _byte_extended_read( unsigned int cluster, 118 unsigned int address ); 119 unsigned int _word_extended_read( unsigned int cluster, 120 unsigned int address ); 112 volatile unsigned char _byte_extended_read( unsigned int cluster, 113 unsigned int address ); 114 volatile unsigned int _word_extended_read( unsigned int cluster, 115 unsigned int address ); 116 121 117 void _word_extended_write( unsigned int cluster, 122 118 unsigned int address,
Note: See TracChangeset
for help on using the changeset viewer.