Changeset 744 for trunk/softs
- Timestamp:
- Jul 10, 2014, 11:23:57 AM (10 years ago)
- Location:
- trunk/softs
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/softs/giet_tsar/giet.S
r743 r744 4 4 * Date : 15/01/2014 5 5 ********************************************************************************* 6 * This is a very simple Interrupts/Exception/Traps handler for a generic 6 * This is a very simple Interrupts/Exception/Traps handler for a generic 7 7 * multi-clusters / multi-processors TSAR architecture (up to 256 clusters, 8 * up to 4 processors per cluster). 8 * up to 4 processors per cluster). 9 9 * The physical address is 40 bits, and the 8 MSB bits A[39:32] define the 10 10 * cluster index. … … 15 15 .section .giet,"ax",@progbits 16 16 .align 2 17 .global _interrupt_vector 17 .global _interrupt_vector 18 18 19 19 .extern seg_xcu_base … … 78 78 * System Call Handler 79 79 * 80 * As the GIET_TSAR does not support system calls, 80 * As the GIET_TSAR does not support system calls, 81 81 * an error message is displayed on TTY0, the program is killed. 82 82 ****************************************************************/ … … 97 97 98 98 mfc0 $4, $14 /* $4 <= EPC */ 99 la $5, _itoa_buffer /* $5 <= buffer address */ 99 la $5, _itoa_buffer /* $5 <= buffer address */ 100 100 addiu $5, $5, 2 /* skip the 0x prefix */ 101 101 jal _itoa_hex /* fill the buffer */ … … 108 108 nop 109 109 110 j _exit /* end of program */ 110 j _exit /* end of program */ 111 111 112 112 _itoa_buffer: .ascii "0x00000000" … … 122 122 * It makes the assumption that there is only one interrupt per 123 123 * entry in the interrupt vector (it can be PTI, HWI, or WTI). 124 * In case of a multi-clusters architecture, it exist one XCU 125 * per cluster, and the base address of the ICU segment depends 124 * In case of a multi-clusters architecture, it exist one XCU 125 * per cluster, and the base address of the ICU segment depends 126 126 * on both the cluster_xy and the proc_id: 127 127 * - base_address = seg_xcu_base + (32*local_id) + (4G*cluster_xy) … … 164 164 sw $31, 4*21($29) /* save $31 */ 165 165 mfc0 $27, $14 166 sw $27, 4*22($29) /* save EPC */ 166 sw $27, 4*22($29) /* save EPC */ 167 167 168 168 /* XICU PRIO register address computation */ … … 170 170 /* and we must use the physical address extension */ 171 171 mfc0 $10, $15, 1 /* $10 <= proc_id */ 172 andi $10, $10, 0x3FF /* at most 1024 processors */ 172 andi $10, $10, 0x3FF /* at most 1024 processors */ 173 173 li $11, NB_PROCS_MAX 174 174 divu $10, $11 … … 194 194 andi $27, $15, 0x4 /* test bit W in PRIO register */ 195 195 bne $27, $0, _int_WTI /* branch to WTI handler */ 196 196 197 197 /* exit interrupt handler: restore registers */ 198 198 _int_restore: … … 200 200 lw $1, 4*4($29) 201 201 .set at 202 lw $2, 4*5($29) 203 lw $3, 4*6($29) 202 lw $2, 4*5($29) 203 lw $3, 4*6($29) 204 204 lw $4, 4*7($29) 205 lw $5, 4*8($29) 205 lw $5, 4*8($29) 206 206 lw $6, 4*9($29) 207 lw $7, 4*10($29) 207 lw $7, 4*10($29) 208 208 lw $8, 4*11($29) 209 209 lw $9, 4*12($29) … … 217 217 lw $25, 4*20($29) 218 218 lw $31, 4*21($29) 219 lw $27, 4*22($29) /* get EPC */ 219 lw $27, 4*22($29) /* get EPC */ 220 220 addiu $29, $29, 23*4 /* restore SP */ 221 221 mtc0 $27, $14 /* restore EPC */ … … 233 233 la $27, _interrupt_vector 234 234 addu $26, $26, $27 235 lw $26, ($26) /* read ISR address */ 235 lw $26, ($26) /* read ISR address */ 236 236 jalr $26 /* call ISR */ 237 237 nop … … 246 246 la $27, _interrupt_vector 247 247 addu $26, $26, $27 /* $26 <= &ISR[HWI_INDEX */ 248 lw $26, ($26) /* read ISR address */ 248 lw $26, ($26) /* read ISR address */ 249 249 jalr $26 /* call ISR */ 250 250 nop … … 262 262 la $27, _interrupt_vector 263 263 addu $26, $26, $27 /* $26 <= &ISR[WTI_INDEX] */ 264 lw $26, ($26) /* read ISR address */ 264 lw $26, ($26) /* read ISR address */ 265 265 jalr $26 /* call ISR */ 266 266 nop 267 267 j _int_restore /* return from INT handler */ 268 268 nop 269 269 270 270 /* The default ISR is called when no specific ISR has been installed */ 271 271 /* in the interrupt vector. It simply displays a message on TTY0 */ … … 273 273 isr_default: 274 274 addiu $29, $29, -20 /* get space in stack */ 275 sw $31, 16($29) /* to save the return address */ 275 sw $31, 16($29) /* to save the return address */ 276 276 la $4, _msg_default /* $4 <= string address */ 277 277 addi $5, $0, 36 /* $5 <= string length */ 278 278 li $6, 0 /* $6 <= TTY0 */ 279 jal _tty_write 280 lw $31, 16($29) /* restore return address */ 279 jal _tty_write 280 lw $31, 16($29) /* restore return address */ 281 281 addiu $29, $29, 20 /* free space */ 282 282 jr $31 /* returns to interrupt handler */ … … 284 284 /**************************************************************** 285 285 * Interrupt Vector Table (indexed by interrupt index) 286 * 32 words corresponding to 32 ISR addresses 286 * 32 words corresponding to 32 ISR addresses 287 287 ****************************************************************/ 288 288 _interrupt_vector: … … 355 355 li $5, 36 /* $5 <= message length */ 356 356 li $6, 0 /* $6 <= TTY0 */ 357 jal _tty_write 357 jal _tty_write 358 358 nop 359 359 … … 362 362 li $5, 8 /* $5 <= message length */ 363 363 li $6, 0 /* $6 <= TTY0 */ 364 jal _tty_write 365 nop 366 364 jal _tty_write 365 nop 366 367 367 mfc0 $4, $14 /* $4 <= EPC value */ 368 368 la $5, _itoa_buffer /* $5 <= buffer address */ … … 377 377 nop 378 378 379 /* display BAR value */ 379 /* display BAR value */ 380 380 la $4, _msg_bar /* $4 <= message address */ 381 381 li $5, 8 /* $5 <= message length */ … … 385 385 386 386 mfc0 $4, $8 /* $4 <= BAR value */ 387 la $5, _itoa_buffer /* $5 <= buffer address */ 388 addiu $5, $5, 2 /* skip 0x prefix */ 387 la $5, _itoa_buffer /* $5 <= buffer address */ 388 addiu $5, $5, 2 /* skip 0x prefix */ 389 389 jal _itoa_hex /* fill buffer */ 390 390 nop … … 393 393 li $5, 10 /* $5 <= message length */ 394 394 li $6, 0 /* $6 <= TTY0 */ 395 jal _tty_write 396 nop 397 398 395 jal _tty_write 396 nop 397 398 399 399 /* release the lock on TTY0 */ 400 400 li $4, 0 -
trunk/softs/giet_tsar/mips32_registers.h
r622 r744 58 58 /* CP2 registers */ 59 59 60 #define CP2_PTPR $0 60 #define CP2_PTPR $0 61 61 #define CP2_MODE $1 62 62 #define CP2_ICACHE_FLUSH $2 63 63 #define CP2_DCACHE_FLUSH $3 64 #define CP2_ITLB_INVAL $4 65 #define CP2_DTLB_INVAL $5 66 #define CP2_ICACHE_INVAL $6 64 #define CP2_ITLB_INVAL $4 65 #define CP2_DTLB_INVAL $5 66 #define CP2_ICACHE_INVAL $6 67 67 #define CP2_DCACHE_INVAL $7 68 #define CP2_ICACHE_PREFETCH $8 69 #define CP2_DCACHE_PREFETCH $9 70 #define CP2_SYNC $10 71 #define CP2_IETR $11 72 #define CP2_DETR $12 68 #define CP2_ICACHE_PREFETCH $8 69 #define CP2_DCACHE_PREFETCH $9 70 #define CP2_SYNC $10 71 #define CP2_IETR $11 72 #define CP2_DETR $12 73 73 #define CP2_IBVAR $13 74 74 #define CP2_DBVAR $14 75 #define CP2_PARAMS $15 76 #define CP2_RELEASE $16 77 #define CP2_DATA_LO $17 78 #define CP2_DATA_HI $18 79 #define CP2_ICACHE_INVAL_PA $19 80 #define CP2_DCACHE_INVAL_PA $20 75 #define CP2_PARAMS $15 76 #define CP2_RELEASE $16 77 #define CP2_DATA_LO $17 78 #define CP2_DATA_HI $18 79 #define CP2_ICACHE_INVAL_PA $19 80 #define CP2_DCACHE_INVAL_PA $20 81 81 #define CP2_PADDR_EXT $24 82 82 #endif -
trunk/softs/giet_tsar/reset.S
r743 r744 5 5 ********************************************************************************* 6 6 * This is a boot code for a generic multi-clusters / multi-processors 7 * TSAR architecture (up to 256 clusters / up to 4 processors per cluster). 7 * TSAR architecture (up to 256 clusters / up to 4 processors per cluster). 8 8 * The physical address is 40 bits, and the 8 MSB bits A[39:32] define the 9 9 * cluster index. 10 10 * 11 * As we don't want to use the virtual memory, the physical address is 11 * As we don't want to use the virtual memory, the physical address is 12 12 * equal to the virtual address (identity mapping) and all processors stacks 13 * and code segments are allocated in the physical memory bank in cluster 0. 13 * and code segments are allocated in the physical memory bank in cluster 0. 14 14 * 15 15 * Both the reset base address and the kernel base address must be redefined … … 22 22 * There is two sets of peripherals: 23 23 * 24 * 1) A block device and a single channel TTY controller are available 24 * 1) A block device and a single channel TTY controller are available 25 25 * in cluster(0,0). 26 26 * 27 * 2) Other peripherals (including another Blockdevice, a multi-channels TTY 27 * 2) Other peripherals (including another Blockdevice, a multi-channels TTY 28 28 * contrÃŽler, a Frame buffer) are located in cluster_io. 29 29 * For those externals peripherals, hardware interrupts (HWI) are translated … … 37 37 * - Only processor 0 initializes the IOPIC component. 38 38 * - Each processor initializes its private XCU mask. 39 * - Each processor initializes the Status Register (SR) 39 * - Each processor initializes the Status Register (SR) 40 40 * - Each processor jumps to the same main address in kernel mode... 41 41 ********************************************************************************/ … … 56 56 .extern main 57 57 58 .globl reset 58 .globl reset 59 59 .ent reset 60 60 .align 2 … … 95 95 96 96 la $26, _interrupt_vector /* interrupt vector address */ 97 la $27, _mmc_isr 97 la $27, _mmc_isr 98 98 sw $27, 32($26) /* interrupt_vector[8] <= _mmc_isr */ 99 la $27, _ioc_isr 99 la $27, _ioc_isr 100 100 sw $27, 36($26) /* interrupt_vector[9] <= _ioc_isr */ 101 la $27, _tty_isr 101 la $27, _tty_isr 102 102 sw $27, 40($26) /* interrupt_vector[10] <= _tty_isr */ 103 103 … … 129 129 130 130 #endif 131 131 132 132 reset_xcu: 133 133 … … 149 149 150 150 /* initializes SR register */ 151 li $26, 0x0000FF01 151 li $26, 0x0000FF01 152 152 mtc0 $26, $12 /* SR <= kernel mode / IRQ enable */ 153 153 -
trunk/softs/giet_tsar/stdio.c
r743 r744 1 1 //////////////////////////////////////////////////////////////////////////////////////// 2 2 // File : stdio.c 3 // Written by Alain Greiner 4 // Date : janvier 2014 3 // Written by Alain Greiner 4 // Date : janvier 2014 5 5 // 6 6 // This file defines various functions that can be used by applications to access … … 112 112 // Memcopy taken from MutekH. 113 113 //////////////////////////////////////////////////////////////////////////////////////// 114 in_drivers void* _memcpy( void* _dst, 115 const void* _src, 114 in_drivers void* _memcpy( void* _dst, 115 const void* _src, 116 116 unsigned int size ) 117 117 { … … 120 120 if ( ! ((unsigned int)dst & 3) && ! ((unsigned int)src & 3) ) 121 121 { 122 while (size > 3) 122 while (size > 3) 123 123 { 124 124 *dst++ = *src++; … … 130 130 unsigned char *csrc = (unsigned char*)src; 131 131 132 while (size--) 132 while (size--) 133 133 { 134 134 *cdst++ = *csrc++; … … 141 141 in_drivers void _extended_memcpy( unsigned int dst_cluster, 142 142 unsigned int dst_address, 143 unsigned int src_cluster,144 143 unsigned int src_address, 145 144 unsigned int length ) … … 205 204 { 206 205 asm volatile( 207 "mfc0 $8, $12 \n" 206 "mfc0 $8, $12 \n" 208 207 "ori $8, $8, 1 \n" 209 208 "mtc0 $8, $12 \n" … … 260 259 261 260 //////////////////////////////////////////////////////////////////////////// 262 // This function makes a physical read access to a 32 bits word in memory, 261 // This function makes a physical read access to a 32 bits word in memory, 263 262 // after a temporary paddr extension. 264 263 //////////////////////////////////////////////////////////////////////////// … … 273 272 "mtc0 $3, $12 \n" /* IRQ disabled */ 274 273 275 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 274 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 276 275 "lw %0, 0(%1) \n" /* value <= *paddr */ 277 276 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ … … 285 284 } 286 285 //////////////////////////////////////////////////////////////////////////// 287 // This function makes a physical read access to a single byte in memory, 286 // This function makes a physical read access to a single byte in memory, 288 287 // after a temporary paddr extension. 289 288 //////////////////////////////////////////////////////////////////////////// … … 298 297 "mtc0 $3, $12 \n" /* IRQ disabled */ 299 298 300 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 299 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 301 300 "lb %0, 0(%1) \n" /* value <= *paddr */ 302 301 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ … … 310 309 } 311 310 //////////////////////////////////////////////////////////////////////////// 312 // This function makes a physical write access to a 32 bits word in memory, 311 // This function makes a physical write access to a 32 bits word in memory, 313 312 // after a temporary DTLB address extension. 314 313 //////////////////////////////////////////////////////////////////////////// 315 in_drivers void _word_extended_write( unsigned int cluster, 314 in_drivers void _word_extended_write( unsigned int cluster, 316 315 unsigned int address, 317 unsigned int word ) 316 unsigned int word ) 318 317 { 319 318 int sr = _sr_read(); … … 323 322 "mtc0 $3, $12 \n" /* IRQ disabled */ 324 323 325 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 324 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 326 325 "sw %0, 0(%1) \n" /* *paddr <= value */ 327 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 326 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 328 327 329 328 "sync \n" … … 335 334 } 336 335 //////////////////////////////////////////////////////////////////////////// 337 // This function makes a physical write access to single byte in memory, 336 // This function makes a physical write access to single byte in memory, 338 337 // after a temporary DTLB de-activation and address extension. 339 338 //////////////////////////////////////////////////////////////////////////// 340 in_drivers void _byte_extended_write( unsigned int cluster, 339 in_drivers void _byte_extended_write( unsigned int cluster, 341 340 unsigned int address, 342 unsigned char byte ) 341 unsigned char byte ) 343 342 { 344 343 int sr = _sr_read(); … … 348 347 "mtc0 $3, $12 \n" /* IRQ disabled */ 349 348 350 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 349 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 351 350 "sb %0, 0(%1) \n" /* *paddr <= value */ 352 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 351 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 353 352 354 353 "sync \n" … … 361 360 362 361 /////////////////////////////////////////////////////////////////////////////////////// 363 // Exit (suicide) after printing message on TTY0 362 // Exit (suicide) after printing message on TTY0 364 363 /////////////////////////////////////////////////////////////////////////////////////// 365 364 in_drivers void _exit() … … 418 417 // - If there is only one terminal, it is supposed to be shared, and used by 419 418 // all processors: a lock must be taken before display. 420 // - If there is several terminals, and the number of processors is smaller 421 // than the number of terminals, there is one terminal per processor, but 419 // - If there is several terminals, and the number of processors is smaller 420 // than the number of terminals, there is one terminal per processor, but 422 421 // the TTY index is not equal to the proc_id, due to cluster indexing policy: 423 422 // proc_id = cluster_xy * NB_PROCS_MAX + local_id (with cluster_xy = x << Y_WIDTH + y) … … 434 433 // returns the number of characters that have been actually written. 435 434 /////////////////////////////////////////////////////////////////////////////////////// 436 in_drivers int _tty_write( char* buffer, 437 unsigned int length, 435 in_drivers int _tty_write( char* buffer, 436 unsigned int length, 438 437 unsigned int channel ) 439 438 { … … 464 463 // and returns 1 if the register is full. 465 464 /////////////////////////////////////////////////////////////////////////////////////// 466 in_drivers int _tty_read( char* buffer, 465 in_drivers int _tty_read( char* buffer, 467 466 unsigned int channel ) 468 467 { … … 493 492 // This function displays a 32 bits unsigned int as an hexa string on TTY0. 494 493 /////////////////////////////////////////////////////////////////////////////// 495 in_drivers void _tty_putx(unsigned int val) 494 in_drivers void _tty_putx(unsigned int val) 496 495 { 497 496 static const char HexaTab[] = "0123456789ABCDEF"; … … 503 502 buf[10] = 0; 504 503 505 for (c = 0; c < 8; c++) 506 { 504 for (c = 0; c < 8; c++) 505 { 507 506 buf[9 - c] = HexaTab[val & 0xF]; 508 507 val = val >> 4; … … 514 513 // This function displays a 32 bits unsigned int as a decimal string on TTY0. 515 514 /////////////////////////////////////////////////////////////////////////////// 516 in_drivers void _tty_putd( unsigned int val ) 515 in_drivers void _tty_putd( unsigned int val ) 517 516 { 518 517 static const char DecTab[] = "0123456789"; … … 523 522 buf[10] = 0; 524 523 525 for (i = 0; i < 10; i++) 526 { 527 if ((val != 0) || (i == 0)) 524 for (i = 0; i < 10; i++) 525 { 526 if ((val != 0) || (i == 0)) 528 527 { 529 528 buf[9 - i] = DecTab[val % 10]; 530 529 first = 9 - i; 531 530 } 532 else 531 else 533 532 { 534 533 break; … … 540 539 541 540 ////////////////////////////////////////////////////////////////////////////// 542 // This function try to take the hardwired lock protecting exclusive access 541 // This function try to take the hardwired lock protecting exclusive access 543 542 // to TTY terminal identified by the channel argument. 544 543 // It returns only when the lock has been successfully taken. … … 552 551 553 552 ////////////////////////////////////////////////////////////////////////////// 554 // This function releases the hardwired lock protecting exclusive access 553 // This function releases the hardwired lock protecting exclusive access 555 554 // to TTY terminal identified by the channel argument. 556 555 ////////////////////////////////////////////////////////////////////////////// … … 577 576 // check TTY channel 578 577 l = (proc_id % NB_PROCS_MAX); 579 x = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 578 x = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 580 579 y = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1); 581 580 channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l; … … 600 599 // The <DEL> character is interpreted, and previous characters can be 601 600 // cancelled. All others characters are ignored. 602 // When the <LF> or <CR> character is received, the string is converted 601 // When the <LF> or <CR> character is received, the string is converted 603 602 // to an unsigned int value. If the number of decimal digit is too large 604 603 // for the 32 bits range, the zero value is returned. … … 624 623 // check TTY channel 625 624 l = (proc_id % NB_PROCS_MAX); 626 x = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 625 x = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 627 626 y = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1); 628 627 channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l; … … 702 701 703 702 // compute TTY channel : 704 // if the number of TTY channels is smaller 703 // if the number of TTY channels is smaller 705 704 // than the number of clusters, use TTY_0_0 706 705 // else, TTY channel <= cluster index … … 711 710 else 712 711 { 713 x = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 712 x = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 714 713 y = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1); 715 714 channel = (x * Y_SIZE + y); 716 715 } 717 716 718 // take the TTY lock 717 // take the TTY lock 719 718 _tty_get_lock( channel ); 720 719 721 720 printf_text: 722 721 723 while (*format) 722 while (*format) 724 723 { 725 724 unsigned int i; 726 725 for (i = 0; format[i] && format[i] != '%'; i++) 727 726 ; 728 if (i) 727 if (i) 729 728 { 730 729 _tty_write( format, i, channel ); 731 730 format += i; 732 731 } 733 if (*format == '%') 732 if (*format == '%') 734 733 { 735 734 format++; … … 762 761 break; 763 762 case ('d'): // decimal signed integer 764 if (val < 0) 763 if (val < 0) 765 764 { 766 765 val = -val; … … 768 767 } 769 768 case ('u'): // decimal unsigned integer 770 for( i=0 ; i<10 ; i++) 769 for( i=0 ; i<10 ; i++) 771 770 { 772 771 buf[9-i] = HexaTab[val % 10]; … … 778 777 case ('x'): // hexadecimal integer 779 778 _tty_write( "0x", 2, channel ); 780 for( i=0 ; i<8 ; i++) 779 for( i=0 ; i<8 ; i++) 781 780 { 782 781 buf[7-i] = HexaTab[val % 16U]; … … 858 857 ////////////////////////////////////////////////////////////////////////////////////////// 859 858 // The block size is 512 bytes. 860 // The functions below use the three variables _ioc_lock _ioc_done, 859 // The functions below use the three variables _ioc_lock _ioc_done, 861 860 // and _ioc_status for synchronisation. 862 861 // - As the IOC component can be used by several programs running in parallel, 863 862 // the _ioc_lock variable guaranties exclusive access to the device. 864 863 // The _ioc_read() and _ioc_write() functions use atomic LL/SC to get the lock. 865 // and set _ioc_lock to a non zero value. 864 // and set _ioc_lock to a non zero value. 866 865 // The _ioc_write() and _ioc_read() functions are blocking, polling the _ioc_lock 867 866 // variable until the device is available. … … 873 872 // reset the _ioc_done variable to zero, and releases the _ioc_lock variable. 874 873 /////////////////////////////////////////////////////////////////////////////////////// 875 // If USE_RAMDISK is set, we access a "virtual" block device controler implemented 874 // If USE_RAMDISK is set, we access a "virtual" block device controler implemented 876 875 // as a memory-mapped segment in cluster [0,0] at address seg_ramdisk_base. 877 876 // The tranfer being fully synchronous, the IOC interrupt is not activated. … … 879 878 880 879 /////////////////////////////////////////////////////////////////////////////////////// 881 // This blocking function is used by the _ioc_read() and _ioc_write() functions 880 // This blocking function is used by the _ioc_read() and _ioc_write() functions 882 881 // to get _ioc_lock using LL/SC. 883 882 /////////////////////////////////////////////////////////////////////////////////////// 884 883 in_drivers void _ioc_get_lock() 885 884 { 886 register unsigned int* plock = (unsigned int*)&_ioc_lock; 885 register unsigned int* plock = (unsigned int*)&_ioc_lock; 887 886 888 887 asm volatile ( … … 890 889 "ll $2, 0(%0) \n" // $2 <= _ioc_lock 891 890 "bnez $2, 1b \n" // retry if busy 892 "li $3, 1 \n" // prepare argument for sc 891 "li $3, 1 \n" // prepare argument for sc 893 892 "sc $3, 0(%0) \n" // try to set _ioc_busy 894 "beqz $3, 1b \n" // retry if not atomic 893 "beqz $3, 1b \n" // retry if not atomic 895 894 ::"r"(plock) :"$2","$3"); 896 895 } … … 903 902 // - ext : cluster index for the memory buffer 904 903 /////////////////////////////////////////////////////////////////////////////////////// 905 in_drivers void _ioc_write( size_t lba, 906 void* buffer, 904 in_drivers void _ioc_write( size_t lba, 905 void* buffer, 907 906 size_t count, 908 907 size_t ext ) … … 923 922 src_address, 924 923 count*512 ); 925 924 926 925 _ioc_status = BLOCK_DEVICE_WRITE_SUCCESS; 927 926 _ioc_done = 1; … … 946 945 // - ext : cluster index for the memory buffer 947 946 /////////////////////////////////////////////////////////////////////////////////////// 948 in_drivers void _ioc_read( size_t lba, 949 void* buffer, 947 in_drivers void _ioc_read( size_t lba, 948 void* buffer, 950 949 size_t count, 951 950 size_t ext ) … … 995 994 { 996 995 // waiting for completion 997 while (_ioc_done == 0) asm volatile("nop"); 998 996 while (_ioc_done == 0) asm volatile("nop"); 997 999 998 // reset synchronisation variables 1000 999 _ioc_done = 0; … … 1028 1027 // FRAME_BUFFER 1029 1028 ////////////////////////////////////////////////////////////////////////////////////// 1030 // The _fb_sync_write & _fb_sync_read functions use a memcpy strategy to implement 1029 // The _fb_sync_write & _fb_sync_read functions use a memcpy strategy to implement 1031 1030 // the transfer between a data buffer and the frame buffer. 1032 1031 // They are blocking until completion of the transfer. … … 1041 1040 // - ext : cluster_xy for the user buffer 1042 1041 ////////////////////////////////////////////////////////////////////////////////////// 1043 in_drivers void _fb_sync_write( unsigned int offset, 1044 unsigned int buffer, 1042 in_drivers void _fb_sync_write( unsigned int offset, 1043 unsigned int buffer, 1045 1044 unsigned int length, 1046 1045 unsigned int ext ) … … 1049 1048 unsigned int src_cluster = ext; 1050 1049 unsigned int dst_address = (unsigned int)&seg_fbf_base + offset; 1051 unsigned int dst_cluster = (X_IO << Y_WIDTH) | Y_IO; // cluster_xy for I/O 1052 1053 _extended_memcpy( dst_cluster, 1050 1051 _extended_memcpy( CLUSTER_IO, 1054 1052 dst_address, 1055 1053 src_cluster, … … 1066 1064 // - ext : cluster_xy for the user buffer 1067 1065 ////////////////////////////////////////////////////////////////////////////////////// 1068 in_drivers void _fb_sync_read( unsigned int offset, 1069 unsigned int buffer, 1066 in_drivers void _fb_sync_read( unsigned int offset, 1067 unsigned int buffer, 1070 1068 unsigned int length, 1071 1069 unsigned int ext ) … … 1074 1072 unsigned int dst_cluster = ext; 1075 1073 unsigned int src_address = (unsigned int)&seg_fbf_base + offset; 1076 unsigned int src_cluster = (X_IO << Y_WIDTH) | Y_IO; // cluster_xy for I/O1077 1074 1078 1075 _extended_memcpy( dst_cluster, 1079 1076 dst_address, 1080 src_cluster,1077 CLUSTER_IO, 1081 1078 src_address, 1082 1079 length ); … … 1093 1090 //int* mmc_address = (int*)&seg_mmc_base; 1094 1091 unsigned int cluster_xy = _procid() / NB_PROCS_MAX; 1095 1092 1096 1093 _tty_printf( "WRITE ERROR signaled by Memory Cache in cluster %x\n", cluster_xy ); 1097 1094 } 1098 1095 1099 1096 /////////////////////////////////////////////////////////////////////////////////////// 1100 // Release a software spin-lock 1097 // Release a software spin-lock 1101 1098 /////////////////////////////////////////////////////////////////////////////////////// 1102 1099 in_drivers void _release_lock(size_t index) 1103 1100 1104 1101 { 1105 if( index >= NB_LOCKS ) 1102 if( index >= NB_LOCKS ) 1106 1103 { 1107 1104 _tty_get_lock( 0 ); … … 1110 1107 _exit(); 1111 1108 } 1112 1109 1113 1110 _spin_lock[index] = 0; 1114 1111 } … … 1132 1129 1133 1130 register int delay = ((_proctime() +_procid()) & 0xF) << 4; 1134 register int * plock = (int *) &_spin_lock[index]; 1131 register int * plock = (int *) &_spin_lock[index]; 1135 1132 1136 1133 asm volatile ("_locks_llsc: \n" 1137 1134 "ll $2, 0(%0) \n" // $2 <= _locks_lock 1138 1135 "bnez $2, _locks_delay \n" // random delay if busy 1139 "li $3, 1 \n" // prepare argument for sc 1136 "li $3, 1 \n" // prepare argument for sc 1140 1137 "sc $3, 0(%0) \n" // try to set _locks_busy 1141 "bnez $3, _locks_ok \n" // exit if atomic 1138 "bnez $3, _locks_ok \n" // exit if atomic 1142 1139 "_locks_delay: \n" 1143 1140 "move $4, %1 \n" // $4 <= delay … … 1155 1152 // - barrier_count[index] <= N 1156 1153 // - barrier_lock[index] <= 0 1157 // All tasks try to initialize the barrier, but the initialisation 1154 // All tasks try to initialize the barrier, but the initialisation 1158 1155 // is done by only one task, using LL/SC instructions. 1159 // This cooperative initialisation is questionnable, 1156 // This cooperative initialisation is questionnable, 1160 1157 // because the barrier can ony be initialised once... 1161 1158 ////////////////////////////////////////////////////////////////////////////////////// … … 1176 1173 // parallel initialisation using atomic instructions LL/SC 1177 1174 asm volatile ("_barrier_init_test: \n" 1178 "ll $2, 0(%0) \n" // read barrier_value 1175 "ll $2, 0(%0) \n" // read barrier_value 1179 1176 "bnez $2, _barrier_init_done \n" 1180 1177 "move $3, %3 \n" 1181 1178 "sc $3, 0(%0) \n" // try to write barrier_value 1182 1179 "beqz $3, _barrier_init_test \n" 1183 "move $3, %3 \n" 1180 "move $3, %3 \n" 1184 1181 "sw $3, 0(%1) \n" // barrier_count <= barrier_value 1185 "move $3, $0 \n" // 1182 "move $3, $0 \n" // 1186 1183 "sw $3, 0(%2) \n" // barrier_lock <= 0 1187 1184 "_barrier_init_done: \n" … … 1190 1187 1191 1188 ////////////////////////////////////////////////////////////////////////////////////// 1192 // This blocking function uses a busy_wait technics (on the barrier_lock value), 1193 // because the GIET does not support dynamic scheduling/descheduling of tasks. 1189 // This blocking function uses a busy_wait technics (on the barrier_lock value), 1190 // because the GIET does not support dynamic scheduling/descheduling of tasks. 1194 1191 // The barrier state is actually defined by two variables: 1195 1192 // _barrier_count[index] define the number of particpants that are waiting 1196 // _barrier_lock[index] define the bool variable whose value is polled 1193 // _barrier_lock[index] define the bool variable whose value is polled 1197 1194 // The last participant change the value of _barrier_lock[index] to release the barrier... 1198 1195 // There is at most 16 independant barriers, and an error is returned … … 1201 1198 in_drivers void _barrier_wait(unsigned int index) 1202 1199 { 1203 register int* pcount = (int*)&_barrier_count[index]; 1200 register int* pcount = (int*)&_barrier_count[index]; 1204 1201 register int count; 1205 int lock = _barrier_lock[index]; 1202 int lock = _barrier_lock[index]; 1206 1203 1207 1204 if ( index >= NB_BARRIERS ) … … 1212 1209 _exit(); 1213 1210 } 1214 1211 1215 1212 // parallel decrement _barrier_count[index] using atomic instructions LL/SC 1216 1213 // input : pointer on _barrier_count[index] … … 1238 1235 while ( lock == _barrier_lock[index] ); 1239 1236 } 1240 } 1237 } 1241 1238 1242 1239 -
trunk/softs/giet_tsar/stdio.h
r743 r744 1 1 //////////////////////////////////////////////////////////////////////////////////////// 2 2 // File : stdio.h 3 // Written by Alain Greiner 3 // Written by Alain Greiner 4 4 // Date : 17/01/2014 5 5 // … … 95 95 void _mmc_isr(); 96 96 97 void _fb_sync_write( unsigned int offset, 97 void _fb_sync_write( unsigned int offset, 98 98 unsigned int buffer, 99 99 unsigned int length, 100 100 unsigned int ext ); 101 void _fb_sync_read( unsigned int offset, 101 void _fb_sync_read( unsigned int offset, 102 102 unsigned int buffer, 103 103 unsigned int length, … … 110 110 void _barrier_wait(size_t index); 111 111 112 volatile unsigned char _byte_extended_read( unsigned int cluster, 112 volatile unsigned char _byte_extended_read( unsigned int cluster, 113 113 unsigned int address ); 114 volatile unsigned int _word_extended_read( unsigned int cluster, 114 volatile unsigned int _word_extended_read( unsigned int cluster, 115 115 unsigned int address ); 116 116 117 void _word_extended_write( unsigned int cluster, 118 unsigned int address, 117 void _word_extended_write( unsigned int cluster, 118 unsigned int address, 119 119 unsigned int word ); 120 void _byte_extended_write( unsigned int cluster, 121 unsigned int address, 120 void _byte_extended_write( unsigned int cluster, 121 unsigned int address, 122 122 unsigned char byte ); 123 123 #endif -
trunk/softs/soft_sort_giet/Makefile
r626 r744 4 4 DU = mipsel-unknown-elf-objdump 5 5 6 OBJS = 7 8 9 6 OBJS = reset.o \ 7 giet.o \ 8 stdio.o \ 9 main.o 10 10 11 CFLAGS = -Wall -mno-gpopt -ffreestanding -fomit-frame-pointer -mips32 -ggdb11 CFLAGS = -Wall -mno-gpopt -ffreestanding -fomit-frame-pointer -mips32 12 12 13 13 GIET = ../giet_tsar -
trunk/softs/soft_transpose_giet/Makefile
r623 r744 4 4 DU = mipsel-unknown-elf-objdump 5 5 6 OBJS = 7 8 9 6 OBJS = reset.o \ 7 giet.o \ 8 stdio.o \ 9 main.o 10 10 11 CFLAGS = -Wall -mno-gpopt -ffreestanding -fomit-frame-pointer -mips32 -ggdb 11 CFLAGS = -Wall -mno-gpopt -ffreestanding -fomit-frame-pointer -mips32 \ 12 -msoft-float -O2 \ 13 # -ggdb -mlong-calls 12 14 13 15 GIET = ../giet_tsar … … 18 20 19 21 reset.o: $(GIET)/reset.S hard_config.h 20 $(CC) -I. $(CFLAGS) -c -o $@ $<22 $(CC) -I. -I$(GIET) $(CFLAGS) -c -o $@ $< 21 23 $(DU) -D $@ > $@.txt 22 24 -
trunk/softs/soft_transpose_giet/hard_config.h
r632 r744 7 7 #define _HARD_CONFIG_H 8 8 9 #define X_SIZE 210 #define Y_SIZE 29 #define X_SIZE 6 10 #define Y_SIZE 6 11 11 #define X_WIDTH 4 12 12 #define Y_WIDTH 4 13 #define X_IO 0//(X_SIZE - 1) 14 #define Y_IO 0//(Y_SIZE - 1) 13 15 14 #define NB_PROCS_MAX 116 #define NB_PROCS_MAX 4 15 17 16 #define USE_RAMDISK 117 #define USE_ EXT_IO 018 #define USE_RAMDISK 0 19 #define USE_PIC 1 18 20 19 21 #define NB_DMA_CHANNELS 0 … … 21 23 #define NB_NIC_CHANNELS 0 22 24 #define NB_CMA_CHANNELS 0 23 24 25 #define NB_TTY_CHANNELS 1 25 26 -
trunk/softs/soft_transpose_giet/ldscript
r631 r744 10 10 peripherals are not present in the architecture */ 11 11 12 seg_reset_base = 0x 00000000; /* boot code */12 seg_reset_base = 0xBFC00000; /* boot code */ 13 13 14 14 seg_kcode_base = 0x00010000; /* kernel code */ … … 20 20 21 21 seg_heap_base = 0x00100000; /* heaps for applications */ 22 seg_stack_base = 0x00300000; /* stacks ifor applications*/22 seg_stack_base = 0x00300000; /* stacks for applications */ 23 23 24 seg_ramdisk_base = 0x 00800000; /* virtual disk */24 seg_ramdisk_base = 0xFFFFFFFF; /* virtual disk */ 25 25 26 seg_xcu_base = 0xF0000000; /* controler XCU */ 27 seg_tty_base = 0xF4000000; /* controler TTY */ 28 seg_fbf_base = 0xF3000000; /* controler FBF */ 29 seg_ioc_base = 0xF2000000; /* controler IOC */ 30 seg_nic_base = 0xF7000000; /* controler NIC */ 31 seg_cma_base = 0xF8000000; /* controler CMA */ 32 seg_pic_base = 0xF9000000; /* controler PIC */ 33 seg_mmc_base = 0xE0000000; /* config MMC */ 26 seg_xcu_base = 0xB0000000; /* XCU controller */ 27 seg_dma_base = 0xB1000000; /* DMA controller */ 28 seg_mmc_base = 0xB2000000; /* config MMC */ 29 seg_ioc_base = 0xB3000000; /* IOC controller */ 30 seg_tty_base = 0xB4000000; /* TTY controller */ 31 seg_nic_base = 0xB5000000; /* NIC controller */ 32 seg_cma_base = 0xB6000000; /* CMA controller */ 33 seg_fbf_base = 0xB7000000; /* FBF controller */ 34 seg_pic_base = 0xB8000000; /* PIC controller */ 34 35 36 ENTRY(reset) 35 37 36 38 /* Grouping sections into segments */ … … 60 62 seg_code : { 61 63 *(.text) 64 *(.text.*) 62 65 } 63 66 . = seg_reset_base; -
trunk/softs/soft_transpose_giet/main.c
r631 r744 12 12 #define PRINTF(...) ({ if (lpid == 0) { _tty_printf(__VA_ARGS__); } }) 13 13 14 #define DISPLAY_OK 1 // enable display on frame buffer when non zero15 #define CHECK_VERBOSE 1// display a detailed check on TTY when non zero16 #define INSTRUMENTATION_OK 0 // display statistcs on TTY when non zero14 #define DISPLAY_OK 1 // enable display on frame buffer when non zero 15 #define CHECK_VERBOSE !DISPLAY_OK // display a detailed check on TTY when non zero 16 #define INSTRUMENTATION_OK 0 // display statistcs on TTY when non zero 17 17 18 18 // tricks to read some addresses from ldscript … … 41 41 unsigned int l; // line index for loops 42 42 unsigned int p; // pixel index for loops 43 44 unsigned int * ioc_address = (unsigned int *) &seg_ioc_base; 45 unsigned int block_size = ioc_address[BLOCK_DEVICE_BLOCK_SIZE]; 46 43 unsigned int block_size = _ioc_get_blocksize(); // get IOC block size 47 44 unsigned int proc_id = _procid(); // processor id 48 45 unsigned int nclusters = X_SIZE*Y_SIZE; // number of clusters … … 128 125 LOAD_END[cluster_id][lpid] = _proctime(); 129 126 127 128 _tty_printf("*** Proc [%d,%d,%d] barrier wait (0)\n", x, y, lpid); 130 129 _barrier_wait(0); 131 130
Note: See TracChangeset
for help on using the changeset viewer.