Changeset 490
- Timestamp:
- Jan 16, 2015, 1:24:18 PM (10 years ago)
- Location:
- soft/giet_vm
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_boot/boot.c
r477 r490 166 166 unsigned int _ptabs_max_pt2; 167 167 168 __attribute__((section (".bootdata"))) 169 //volatile struct _boot_init_ok { 170 // unsigned int value; 171 //}__attribute__((aligned(64))); 172 //struct _boot_init_ok boot_init_ok = {0}; 173 volatile unsigned int boot_init_ok = 0; 174 175 __attribute__((section (".bootdata"))) 176 volatile _giet_lock_t lock_tty; 177 178 __attribute__((section (".bootdata"))) 179 volatile _giet_barrier_t barrier_boot; 180 181 __attribute__((section (".bootdata"))) 182 volatile _giet_lock_t lock_next_pt2[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE]; 183 168 184 // Global variables for TTY 169 185 __attribute__((section (".bootdata"))) … … 191 207 __attribute__((section (".bootdata"))) 192 208 unsigned int _tty_rx_buf[NB_TTY_CHANNELS]; 193 194 195 196 209 197 210 ////////////////////////////////////////////////////////////////////////////// … … 209 222 210 223 #if (BOOT_DEBUG_PT > 1) 224 _get_lock(&lock_tty); 211 225 _puts(" - PTE1 in PTAB["); 212 226 _putd( vspace_id ); … … 217 231 _puts("] : vpn = "); 218 232 _putx( vpn ); 219 #endif 233 _puts(" / ppn = "); 234 _putx( ppn ); 235 _puts(" / flags = "); 236 _putx( flags ); 237 _puts("\n"); 238 _release_lock(&lock_tty); 239 #endif 240 241 unsigned int procid = _get_procid(); 242 unsigned int x_cluster = (procid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1); 243 unsigned int y_cluster = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 220 244 221 245 // compute index in PT1 … … 228 252 if ( pt1_pbase == 0 ) 229 253 { 254 _get_lock(&lock_tty); 230 255 _puts("\n[BOOT ERROR] in boot_add_pte1() : illegal pbase address for PTAB["); 231 256 _putd( vspace_id ); … … 234 259 _puts(","); 235 260 _putd( y ); 261 _puts("]"); 262 _puts(" in cluster["); 263 _putd(x_cluster); 264 _puts(","); 265 _putd(y_cluster); 236 266 _puts("]\n"); 267 _release_lock(&lock_tty); 237 268 _exit(); 238 269 } … … 246 277 _physical_write( pt1_pbase + 4*ix1, pte1 ); 247 278 248 #if (BOOT_DEBUG_PT > 1) 249 _puts(" / ppn = "); 250 _putx( ppn ); 251 _puts(" / flags = "); 252 _putx( flags ); 279 #if (BOOT_DEBUG_PT > 1 ) 280 _get_lock(&lock_tty); 281 _puts(" - Write pte1 "); 282 _putx( pte1 ); 283 _puts(" in paddr "); 284 _putl( pt1_pbase + 4*ix1 ); 285 _puts(" in cluster["); 286 _putd(x_cluster); 287 _puts(","); 288 _putd(y_cluster); 289 _puts("]\n"); 253 290 _puts("\n"); 291 _release_lock(&lock_tty); 254 292 #endif 255 293 … … 272 310 273 311 #if (BOOT_DEBUG_PT > 1) 312 _get_lock(&lock_tty); 274 313 _puts(" - PTE2 in PTAB["); 275 314 _putd( vspace_id ); … … 280 319 _puts("] : vpn = "); 281 320 _putx( vpn ); 321 _puts(" / ppn = "); 322 _putx( ppn ); 323 _puts(" / flags = "); 324 _putx( flags ); 325 _puts("\n"); 326 _release_lock(&lock_tty); 282 327 #endif 283 328 … … 298 343 if ( pt1_pbase == 0 ) 299 344 { 345 _get_lock(&lock_tty); 300 346 _puts("\n[BOOT ERROR] in boot_add_pte2() : PTAB["); 301 347 _putd( vspace_id ); … … 305 351 _putd( y ); 306 352 _puts("] undefined\n"); 353 _release_lock(&lock_tty); 307 354 _exit(); 308 355 } 309 356 310 357 // get ptd in PT1 358 _get_lock(&lock_next_pt2[vspace_id][x][y]); 311 359 ptd = _physical_read(pt1_pbase + 4 * ix1); 312 360 … … 337 385 } 338 386 387 _release_lock(&lock_next_pt2[vspace_id][x][y]); 339 388 // set PTE in PT2 : flags & PPN in two 32 bits words 340 389 pte2_paddr = pt2_pbase + 8 * ix2; 341 390 _physical_write(pte2_paddr , (PTE_V |flags) ); 342 391 _physical_write(pte2_paddr + 4 , ppn); 343 344 #if (BOOT_DEBUG_PT > 1)345 _puts(" / ppn = ");346 _putx( ppn );347 _puts(" / flags = ");348 _putx( flags );349 _puts("\n");350 #endif351 392 352 393 } // end boot_add_pte2() … … 498 539 paddr_t paddr = _ptabs_paddr[vsid][x_dest][y_dest] + (ix1<<2); 499 540 unsigned int pte1 = _physical_read( paddr ); 541 #if (BOOT_DEBUG_PT > 1) 542 _get_lock(&lock_tty); 543 _puts("[BOOT DEBUG] "); 544 _puts( vseg->name ); 545 _puts(" in cluster["); 546 _putd( x_dest ); 547 _puts(","); 548 _putd( y_dest ); 549 _puts("] : vbase = "); 550 _putx( vseg->vbase ); 551 _puts(" / paddr = "); 552 _putl( paddr ); 553 _puts(" / pte1 = "); 554 _putx( pte1 ); 555 _puts(" by processor "); 556 _putd(_get_procid()); 557 _puts("\n"); 558 _release_lock(&lock_tty); 559 #endif 500 560 if ( (pte1 & PTE_V) == 0 ) // BPP not allocated yet 501 561 { … … 578 638 579 639 #if BOOT_DEBUG_PT 640 _get_lock(&lock_tty); 580 641 _puts("[BOOT DEBUG] "); 581 642 _puts( vseg->name ); … … 594 655 _putl( vseg->pbase ); 595 656 _puts("\n"); 657 _release_lock(&lock_tty); 596 658 #endif 597 659 … … 779 841 // In each cluster all page tables for the different vspaces must be 780 842 // packed in one vseg occupying one single BPP (Big Physical Page). 843 // 844 // This fonction is executed by the processor[x][y][0], the vsegs mapped in the 845 // cluster[x][y] in map.bin file are handled by the processor[x][y][0] 781 846 // 782 847 // For each vseg, the mapping is done in two steps: … … 803 868 mapping_vseg_t* vseg = _get_vseg_base(header); 804 869 mapping_vobj_t* vobj = _get_vobj_base(header); 870 mapping_cluster_t* cluster ; 871 mapping_pseg_t* pseg ; 805 872 806 873 unsigned int vspace_id; 807 874 unsigned int vseg_id; 875 876 unsigned int procid = _get_procid(); 877 unsigned int x_cluster = (procid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1); 878 unsigned int y_cluster = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 879 unsigned int lpid = procid & ((1<<P_WIDTH)-1); 880 881 if(lpid) 882 { 883 _puts("[BOOT ERROR] boot_ptabs_init() : error local processor id\n"); 884 _exit(); 885 } 808 886 809 887 if (header->vspaces == 0 ) … … 818 896 819 897 #if BOOT_DEBUG_PT 820 _puts("\n[BOOT DEBUG] map PTAB global vsegs\n"); 898 _get_lock(&lock_tty); 899 _puts("\n[BOOT DEBUG] map PTAB global vsegs in cluster["); 900 _putd(x_cluster); 901 _puts(","); 902 _putd(y_cluster); 903 _puts("]"); 904 _puts("\n"); 905 _release_lock(&lock_tty); 821 906 #endif 822 907 … … 824 909 { 825 910 unsigned int vobj_id = vseg[vseg_id].vobj_offset; 826 if ( (vobj[vobj_id].type == VOBJ_TYPE_PTAB) ) 911 pseg = _get_pseg_base(header) + vseg[vseg_id].psegid; 912 cluster = _get_cluster_base(header) + pseg->clusterid; 913 if ( (vobj[vobj_id].type == VOBJ_TYPE_PTAB) && 914 (cluster->x == x_cluster) && 915 (cluster->y == y_cluster)) 827 916 { 828 917 boot_vseg_map( &vseg[vseg_id], 0xFFFFFFFF ); … … 831 920 } 832 921 922 _barrier_wait(&barrier_boot); 923 833 924 for (vseg_id = 0; vseg_id < header->globals; vseg_id++) 834 925 { 835 926 unsigned int vobj_id = vseg[vseg_id].vobj_offset; 836 if ( (vobj[vobj_id].type == VOBJ_TYPE_PTAB) ) 927 pseg = _get_pseg_base(header) + vseg[vseg_id].psegid; 928 cluster = _get_cluster_base(header) + pseg->clusterid; 929 if ( (vobj[vobj_id].type == VOBJ_TYPE_PTAB) && 930 (cluster->x == x_cluster) && 931 (cluster->y == y_cluster)) 837 932 { 838 933 boot_vseg_pte( &vseg[vseg_id], 0xFFFFFFFF ); … … 841 936 } 842 937 938 _barrier_wait(&barrier_boot); 939 843 940 ///////// Phase 2 : global vsegs occupying more than one BPP (one loop) 844 941 845 942 #if BOOT_DEBUG_PT 846 _puts("\n[BOOT DEBUG] map all multi-BPP global vsegs\n"); 847 #endif 943 _get_lock(&lock_tty); 944 _puts("\n[BOOT DEBUG] map all multi-BPP global vseg in cluster["); 945 _putd(x_cluster); 946 _puts(","); 947 _putd(y_cluster); 948 _puts("]"); 949 _puts("\n"); 950 _release_lock(&lock_tty); 951 #endif 848 952 849 953 for (vseg_id = 0; vseg_id < header->globals; vseg_id++) 850 954 { 851 955 unsigned int vobj_id = vseg[vseg_id].vobj_offset; 956 pseg = _get_pseg_base(header) + vseg[vseg_id].psegid; 957 cluster = _get_cluster_base(header) + pseg->clusterid; 852 958 if ( (vobj[vobj_id].length > 0x200000) && 853 (vseg[vseg_id].mapped == 0) ) 959 (vseg[vseg_id].mapped == 0) && 960 (cluster->x == x_cluster) && 961 (cluster->y == y_cluster)) 854 962 { 855 963 boot_vseg_map( &vseg[vseg_id], 0xFFFFFFFF ); … … 862 970 863 971 #if BOOT_DEBUG_PT 864 _puts("\n[BOOT DEBUG] map all others global vsegs\n"); 972 _get_lock(&lock_tty); 973 _puts("\n[BOOT DEBUG] map all others global in cluster[ "); 974 _putd(x_cluster); 975 _puts(","); 976 _putd(y_cluster); 977 _puts("]"); 978 _puts("\n"); 979 _release_lock(&lock_tty); 865 980 #endif 866 981 867 982 for (vseg_id = 0; vseg_id < header->globals; vseg_id++) 868 983 { 869 if ( vseg[vseg_id].mapped == 0 ) 984 unsigned int vobj_id = vseg[vseg_id].vobj_offset; 985 pseg = _get_pseg_base(header) + vseg[vseg_id].psegid; 986 cluster = _get_cluster_base(header) + pseg->clusterid; 987 if ( (vobj[vobj_id].length <= 0x200000) && 988 (vseg[vseg_id].mapped == 0) && 989 (cluster->x == x_cluster) && 990 (cluster->y == y_cluster)) 870 991 { 871 992 boot_vseg_map( &vseg[vseg_id], 0xFFFFFFFF ); … … 881 1002 882 1003 #if BOOT_DEBUG_PT 1004 _get_lock(&lock_tty); 883 1005 _puts("\n[BOOT DEBUG] map private vsegs for vspace "); 884 1006 _puts( vspace[vspace_id].name ); 1007 _puts(" in cluster[ "); 1008 _putd(x_cluster); 1009 _puts(","); 1010 _putd(y_cluster); 1011 _puts("]"); 885 1012 _puts("\n"); 1013 _release_lock(&lock_tty); 886 1014 #endif 887 1015 … … 890 1018 vseg_id++) 891 1019 { 892 boot_vseg_map( &vseg[vseg_id], vspace_id ); 893 vseg[vseg_id].mapped = 1; 894 boot_vseg_pte( &vseg[vseg_id], vspace_id ); 895 } 896 } 897 898 #if (BOOT_DEBUG_PT > 1) 1020 pseg = _get_pseg_base(header) + vseg[vseg_id].psegid; 1021 cluster = _get_cluster_base(header) + pseg->clusterid; 1022 if((vseg[vseg_id].mapped == 0) && 1023 (cluster->x == x_cluster) && 1024 (cluster->y == y_cluster)) 1025 { 1026 boot_vseg_map( &vseg[vseg_id], vspace_id ); 1027 vseg[vseg_id].mapped = 1; 1028 boot_vseg_pte( &vseg[vseg_id], vspace_id ); 1029 } 1030 } 1031 } 1032 1033 #if (BOOT_DEBUG_PT > 2) 1034 _get_lock(&lock_tty); 899 1035 mapping_vseg_t* curr; 900 1036 mapping_pseg_t* pseg = _get_pseg_base(header); … … 926 1062 } 927 1063 } 1064 _release_lock(&lock_tty); 928 1065 #endif 929 1066 … … 1401 1538 1402 1539 // ctx_sr : value required before an eret instruction 1403 unsigned int ctx_sr = 0x 0000FF13;1540 unsigned int ctx_sr = 0x2000FF13; 1404 1541 1405 1542 // ctx_ptpr : page table physical base address (shifted by 13 bit) … … 2121 2258 // This function initialises the physical memory allocators in each 2122 2259 // cluster containing a RAM pseg. 2260 // it is handled by the processor[x][y][0] 2123 2261 ///////////////////////////////////////////////////////////////////////// 2124 2262 void boot_pmem_init() … … 2130 2268 unsigned int cluster_id; 2131 2269 unsigned int pseg_id; 2132 2133 // scan all clusters 2134 for ( cluster_id = 0 ; cluster_id < X_SIZE*Y_SIZE ; cluster_id++ ) 2135 { 2136 // scan the psegs in cluster to find first pseg of type RAM 2137 unsigned int pseg_min = cluster[cluster_id].pseg_offset; 2138 unsigned int pseg_max = pseg_min + cluster[cluster_id].psegs; 2139 for ( pseg_id = pseg_min ; pseg_id < pseg_max ; pseg_id++ ) 2140 { 2141 if ( pseg[pseg_id].type == PSEG_TYPE_RAM ) 2142 { 2143 unsigned int x = cluster[cluster_id].x; 2144 unsigned int y = cluster[cluster_id].y; 2145 unsigned int base = (unsigned int)pseg[pseg_id].base; 2146 unsigned int size = (unsigned int)pseg[pseg_id].length; 2147 _pmem_alloc_init( x, y, base, size ); 2270 unsigned int procid = _get_procid(); 2271 unsigned int x_cluster = (procid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1); 2272 unsigned int y_cluster = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 2273 unsigned int lpid = procid & ((1<<P_WIDTH)-1); 2274 if(lpid) 2275 { 2276 _puts("[BOOT ERROR] boot_pmem_init() : error local processor id\n"); 2277 _exit(); 2278 } // scan all clusters 2279 2280 cluster_id = x_cluster * Y_SIZE + y_cluster; 2281 // scan the psegs in cluster to find first pseg of type RAM 2282 unsigned int pseg_min = cluster[cluster_id].pseg_offset; 2283 unsigned int pseg_max = pseg_min + cluster[cluster_id].psegs; 2284 for ( pseg_id = pseg_min ; pseg_id < pseg_max ; pseg_id++ ) 2285 { 2286 if ( pseg[pseg_id].type == PSEG_TYPE_RAM ) 2287 { 2288 unsigned int x = cluster[cluster_id].x; 2289 unsigned int y = cluster[cluster_id].y; 2290 if(x != x_cluster || y != y_cluster) 2291 { 2292 _puts("[BOOT ERROR] boot_pmem_init() : error cluster id \n"); 2293 _exit(); 2294 } 2295 unsigned int base = (unsigned int)pseg[pseg_id].base; 2296 unsigned int size = (unsigned int)pseg[pseg_id].length; 2297 _pmem_alloc_init( x, y, base, size ); 2148 2298 2149 2299 #if BOOT_DEBUG_PT 2300 _get_lock(&lock_tty); 2150 2301 _puts("\n[BOOT DEBUG] pmem allocator initialised in cluster["); 2151 2302 _putd( x ); … … 2157 2308 _putx( size ); 2158 2309 _puts("\n"); 2159 #endif 2160 break; 2161 }2310 _release_lock(&lock_tty); 2311 #endif 2312 break; 2162 2313 } 2163 2314 } … … 2173 2324 mapping_cluster_t* cluster = _get_cluster_base(header); 2174 2325 unsigned int gpid = _get_procid(); 2175 2326 unsigned int clusterid, p; 2327 2176 2328 if ( gpid == 0 ) // only Processor 0 does it 2177 2329 { … … 2186 2338 _putd(_get_proctime()); 2187 2339 _puts("\n"); 2188 2189 2340 // Load the map.bin file into memory and check it 2190 2341 boot_mapping_init(); … … 2196 2347 _puts("\n"); 2197 2348 2349 _barrier_init(&barrier_boot, X_SIZE*Y_SIZE); 2350 2351 for ( clusterid = 1 ; clusterid < X_SIZE*Y_SIZE ; clusterid++ ) 2352 { 2353 unsigned int x = cluster[clusterid].x; 2354 unsigned int y = cluster[clusterid].y; 2355 unsigned int cluster_xy = (x<<Y_WIDTH) + y; 2356 2357 _xcu_send_wti_paddr( cluster_xy, 0, (unsigned int)boot_entry ); 2358 } 2359 } 2360 //Parallel phase to construct the ptab by each processor[x][y][0] 2361 if( (gpid & ((1 << P_WIDTH) -1)) == 0) 2362 { 2198 2363 // Initializes the physical memory allocators 2199 2364 boot_pmem_init(); 2200 2201 _puts("\n[BOOT] Physical memory allocators initialised at cycle "); 2202 _putd(_get_proctime()); 2203 _puts("\n"); 2204 2205 // Build page tables 2365 // Build ge tables 2206 2366 boot_ptabs_init(); 2207 2208 _puts("\n[BOOT] Page tables initialised at cycle "); 2367 //wait for all processors finished the work 2368 _barrier_wait(&barrier_boot); 2369 2370 if( gpid ) while( boot_init_ok == 0); 2371 } 2372 2373 if ( gpid == 0 ) // only Processor 0 does it 2374 { 2375 _puts("\n[BOOT] Physical memory allocators and Page table initialized at cycle "); 2209 2376 _putd(_get_proctime()); 2210 2377 _puts("\n"); … … 2245 2412 boot_elf_load(); 2246 2413 2247 // P0 starts all other processors2248 unsigned int clusterid, p;2414 // wake up the processors which has constructed the ptab before 2415 boot_init_ok = 1; 2249 2416 2250 2417 for ( clusterid = 0 ; clusterid < X_SIZE*Y_SIZE ; clusterid++ ) … … 2255 2422 unsigned int cluster_xy = (x<<Y_WIDTH) + y; 2256 2423 2257 for ( p = 0 ; p < nprocs; p++ ) 2258 { 2259 if ( (nprocs > 0) && ((clusterid != 0) || (p != 0)) ) 2260 { 2261 _xcu_send_wti( cluster_xy, p, (unsigned int)boot_entry ); 2262 } 2424 for ( p = 1 ; p < nprocs; p++ ) 2425 { 2426 _xcu_send_wti( cluster_xy, p, (unsigned int)boot_entry ); 2263 2427 } 2264 2428 } 2265 2266 2429 } // end monoprocessor boot 2267 2430 -
soft/giet_vm/giet_boot/boot_entry.S
r427 r490 2 2 * file : boot.S 3 3 * date : 01/17/2014 4 * author : Cesar Fuguet & Alain Greiner 4 * author : Cesar Fuguet & Alain Greiner & Hao Liu 5 5 * 6 6 * This file contains the boot_entry() function that is the entry … … 19 19 * to the boot_init() fuction defined in the boot.c file. 20 20 * 21 * - Processor 0 uses a larger stack: 64 Kbytes.21 * - each processor[x][y][0] uses a larger stack: 1,25 Kbytes. 22 22 * - Other processors use a smaller stack: 256 bytes. 23 * => the SEG_BOOT_STACK_SIZE cannot be smaller 320Kytes.24 * ( 64K + 1024 * 256 = 320 Kbytes = 0x50000)23 * => the SEG_BOOT_STACK_SIZE cannot be smaller 512 Kytes. 24 * (256*(1024+256) + (1024 - 256) * 256 = 512 Kbytes = 0x80000) 25 25 */ 26 26 … … 45 45 /* (proc_id is a "continuous" index, while proc_xyl is a "fixed format" index */ 46 46 47 47 48 mfc0 k0, CP0_PROCID 48 49 andi k0, k0, 0xFFF /* k0 <= proc_xyl */ … … 55 56 mflo t5 56 57 addu t5, t5, t4 /* t5 <= cluster_id */ 57 li t7, NB_PROCS_MAX 58 multu t5, t7 59 mflo t0 60 addu t0, t0, t1 /* t0 <= proc_id */ 61 58 li t6, 0x100 * (NB_PROCS_MAX - 1) + 0x500 /* stack size per cluster */ 59 multu t6, t5 60 mflo t7 62 61 63 62 /* All processors initializes stack pointer, depending on proc_id */ 64 63 65 64 la k0, SEG_BOOT_STACK_BASE 66 li k1, 0x10000 /* k1 <= P0 stack size == 64 Kbytes */ 67 addu sp, k0, k1 /* P0 stack from base to (base + 64K) */ 65 addu k0, k0, t7 66 li k1, 0x500 /* k1 <= local P0 stack size == 1,25 Kbytes */ 67 addu sp, k0, k1 /* P0 stack from base to (base + stack size * cluster_id + 1,25K ) */ 68 68 69 li k1, 0x100 /* k1 <= Pi stack size == 256 bytes */70 multu k1, t 069 li k1, 0x100 /* k1 <= Pi stack size == 256 bytes */ 70 multu k1, t1 71 71 mflo k0 /* k0 <= 256 * proc_id */ 72 addu sp, sp, k1 73 addu sp, sp, k0 /* Pi stacks from base + 64K + proc_id*256 */ 72 addu sp, sp, k0 /* Pi stacks from base + stack size * cluster_id + 1,25K + proc_id*256 */ 74 73 75 74 76 75 /* All processors jump to the boot_init function */ 77 76 78 la 79 jr 77 la k0, boot_init 78 jr k0 80 79 nop 81 80 -
soft/giet_vm/giet_common/utils.c
r466 r490 409 409 } 410 410 411 411 /////////////////////////////////////////////////////////////////////////////////// 412 // barrier functions 413 /////////////////////////////////////////////////////////////////////////////////// 414 void _barrier_init( _giet_barrier_t* barrier, 415 unsigned int ntasks ) 416 { 417 barrier->ntasks = ntasks; 418 barrier->count = ntasks; 419 barrier->sense = 0; 420 421 asm volatile ("sync" ::: "memory"); 422 } 423 424 //////////////////////////////////////////// 425 void _barrier_wait( _giet_barrier_t* barrier ) 426 { 427 428 // compute expected sense value 429 unsigned int expected; 430 if ( barrier->sense == 0 ) expected = 1; 431 else expected = 0; 432 433 // parallel decrement barrier counter using atomic instructions LL/SC 434 // - input : pointer on the barrier counter (pcount) 435 // - output : counter value (count) 436 volatile unsigned int* pcount = (unsigned int *)&barrier->count; 437 volatile unsigned int count = 0; // avoid a warning 438 439 asm volatile( "addu $2, %1, $0 \n" 440 "barrier_llsc: \n" 441 "ll $8, 0($2) \n" 442 "addi $9, $8, -1 \n" 443 "sc $9, 0($2) \n" 444 "beqz $9, barrier_llsc \n" 445 "addu %0, $8, $0 \n" 446 : "=r" (count) 447 : "r" (pcount) 448 : "$2", "$8", "$9", "memory" ); 449 450 // the last task re-initializes count and toggle sense, 451 // waking up all other waiting tasks 452 if (count == 1) // last task 453 { 454 barrier->count = barrier->ntasks; 455 barrier->sense = expected; 456 } 457 else // other tasks busy waiting the sense flag 458 { 459 // polling sense flag 460 // input: pointer on the sens flag (psense) 461 // input: expected sense value (expected) 462 volatile unsigned int* psense = (unsigned int *)&barrier->sense; 463 asm volatile ( "barrier_sense: \n" 464 "lw $3, 0(%0) \n" 465 "bne $3, %1, barrier_sense \n" 466 : 467 : "r"(psense), "r"(expected) 468 : "$3" ); 469 } 470 471 asm volatile ("sync" ::: "memory"); 472 } 473 474 /////////////////////////////////////////////////////////////////////////////////// 475 // Locks access functions 476 /////////////////////////////////////////////////////////////////////////////////// 477 478 /////////////////////////////////// 479 void _get_lock( _giet_lock_t* lock ) 480 { 481 register unsigned int* plock = &(lock->value); 482 483 #if NO_HARD_CC 484 485 register unsigned int delay = (_get_proctime() ^ _get_procid() << 4) & 0xFF; 486 if (delay == 0) delay = 0x80; 487 488 asm volatile ( 489 "_lock_llsc: \n" 490 " ll $2, 0(%0) \n" /* $2 <= lock current value */ 491 " bnez $2, _lock_delay \n" /* delay if lock already taken */ 492 " li $3, 1 \n" /* $3 <= argument for sc */ 493 " sc $3, 0(%0) \n" /* try to set lock */ 494 " bnez $3, _lock_ok \n" /* exit if atomic */ 495 " _lock_delay: \n" 496 " move $4, %1 \n" /* $4 <= delay */ 497 " _lock_loop: \n" 498 " addi $4, $4, -1 \n" /* $4 <= $4 - 1 */ 499 " bnez $4, _lock_loop \n" /* test end delay */ 500 " nop \n" 501 " j _lock_llsc \n" /* retry */ 502 " nop \n" 503 " _lock_ok: \n" 504 : 505 :"r"(plock), "r"(delay) 506 :"$2", "$3", "$4", "memory"); 507 #else 508 509 asm volatile ( 510 "_lock_llsc: \n" 511 " lw $2, 0(%0) \n" /* $2 <= lock current value */ 512 " bnez $2, _lock_llsc \n" /* retry if lock already taken */ 513 " nop \n" 514 " ll $2, 0(%0) \n" /* ll_buffer <= lock current value */ 515 " bnez $2, _lock_llsc \n" /* retry if lock already taken */ 516 " li $3, 1 \n" /* $3 <= argument for sc */ 517 " sc $3, 0(%0) \n" /* try to set lock */ 518 " beqz $3, _lock_llsc \n" /* retry if sc failure */ 519 " nop \n" 520 : 521 :"r"(plock) 522 :"$2", "$3", "memory"); 523 #endif 524 525 } 526 527 /////////////////////////////////////// 528 void _release_lock( _giet_lock_t* lock ) 529 { 530 asm volatile ( "sync\n" ::: "memory" ); 531 // sync is necessary because of the TSAR consistency model 532 lock->value = 0; 533 } 412 534 413 535 //////////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_common/utils.h
r455 r490 35 35 extern _ld_symbol_t kernel_init_vbase; 36 36 37 38 39 /////////////////////////////////////////////////////////////////////////////////// 40 // Locks access functions 41 /////////////////////////////////////////////////////////////////////////////////// 42 volatile typedef struct _giet_barrier_s 43 { 44 char name[32]; // barrier name 45 unsigned int sense; // barrier state (toggle) 46 unsigned int ntasks; // total number of expected tasks 47 unsigned int count; // number of not arrived tasks 48 } _giet_barrier_t; 49 50 extern void _barrier_init( _giet_barrier_t* barrier, 51 unsigned int ntasks ); 52 53 extern void _barrier_wait( _giet_barrier_t* barrier ); 54 55 56 /////////////////////////////////////////////////////////////////////////////////// 57 // Locks access functions 58 /////////////////////////////////////////////////////////////////////////////////// 59 volatile typedef struct _giet_lock_s { unsigned int value; 60 unsigned int padding[15]; } _giet_lock_t; 61 62 63 extern void _get_lock(_giet_lock_t* lock); 64 65 extern void _release_lock(_giet_lock_t* lock); 37 66 /////////////////////////////////////////////////////////////////////////////////// 38 67 // CP0 registers access functions -
soft/giet_vm/giet_drivers/xcu_driver.c
r456 r490 181 181 } 182 182 183 //////////////////////////////////////////// 184 void _xcu_send_wti_paddr( unsigned int cluster_xy, 185 unsigned int wti_index, 186 unsigned int wdata ) 187 { 188 #if USE_XCU 189 // parameters checking 190 unsigned int x = cluster_xy >> Y_WIDTH; 191 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 192 if (x >= X_SIZE) _exit(); 193 if (y >= Y_SIZE) _exit(); 194 if (wti_index >= 32) _exit(); 195 196 paddr_t paddr = 197 SEG_XCU_BASE + ((paddr_t)cluster_xy << 32) + 198 (XCU_REG(XCU_WTI_REG, wti_index) << 2); 199 200 _physical_write(paddr, wdata); 201 202 #else 203 _puts("[GIET ERROR] _xcu_send_wti() should not be used if USE_XCU is not set\n"); 204 _exit(); 205 #endif 206 } 183 207 /////////////////////////////////////////////////// 184 208 void _xcu_get_wti_value( unsigned int cluster_xy, -
soft/giet_vm/giet_drivers/xcu_driver.h
r437 r490 93 93 unsigned int wdata ); 94 94 95 /////////////////////////////////////////////////////////////////////////////// 96 // This function writes the "wdata" by physical xcu address value in the mailbox 97 // defined by the "cluster_xy" and "wti_index" arguments. 98 //////////////////////////////////////////////////////////////////////////////// 99 void _xcu_send_wti_paddr( unsigned int cluster_xy, 100 unsigned int wti_index, 101 unsigned int wdata ); 95 102 //////////////////////////////////////////////////////////////////////////////// 96 103 // This function returns the value contained in a WTI mailbox defined by
Note: See TracChangeset
for help on using the changeset viewer.