Changeset 709
- Timestamp:
- Oct 1, 2015, 4:20:46 PM (9 years ago)
- Location:
- soft/giet_vm
- Files:
-
- 2 deleted
- 38 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/Makefile
r701 r709 107 107 build/libs/string.o \ 108 108 build/libs/user_barrier.o \ 109 build/libs/user_lock.o \ 110 build/libs/user_sqt_lock.o 109 build/libs/user_lock.o 111 110 112 111 ### Objects to be linked for the math library -
soft/giet_vm/giet_boot/boot.c
r695 r709 24 24 // - the "map.bin" file contains the hardware architecture description, 25 25 // the set of user applications that will be mapped on the architecture, 26 // and the mapping directives. The mapping includes the placement of t asks26 // and the mapping directives. The mapping includes the placement of threads 27 27 // on processors, and the placement of virtual segments on the physical 28 // segments. It must bestored in the the seg_boot_mapping segment28 // segments. It is stored in the the seg_boot_mapping segment 29 29 // (at address SEG_BOOT_MAPPING_BASE defined in hard_config.h file). 30 30 // - the "kernel.elf" file contains the kernel binary code and data. … … 37 37 // of the software objects (vsegs) on the physical memory banks (psegs). 38 38 // The max number of vspaces (GIET_NB_VSPACE_MAX) is a configuration parameter. 39 // The page table are statically build in the boot phase, and they do not40 // change during execution. For each application, the page tables are replicated41 // in all clusters.39 // The page tables are statically build in the boot phase, and they do not 40 // change during execution. 41 // For each application, the page tables are replicated in all clusters. 42 42 // The GIET_VM uses both small pages (4 Kbytes), and big pages (2 Mbytes). 43 43 // Each page table (one page table per virtual space) is monolithic, and … … 50 50 // 51 51 // 3) The Giet-VM implement one private scheduler per processor. 52 // For each application, the t asks are statically allocated to processors53 // and there is no t askmigration during execution.54 // Each sheduler occupies 8K bytes, and contains up to 14 t askcontexts55 // The t ask context [13] is reserved for the "idle" task that does nothing, and56 // is launched by the scheduler when there is no other runable task.52 // For each application, the threads are statically allocated to processors 53 // and there is no thread migration during execution. 54 // Each sheduler occupies 8K bytes, and contains up to 14 thread contexts 55 // The thread context [13] is reserved for the "idle" thread that does nothing, 56 // and is launched by the scheduler when there is no other runable thread. 57 57 /////////////////////////////////////////////////////////////////////////////////// 58 58 // Implementation Notes: … … 167 167 unsigned int _hba_boot_mode = 1; 168 168 169 // required for concurrent PTAB building 169 170 __attribute__((section(".kdata"))) 170 171 spin_lock_t _ptabs_spin_lock[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE]; … … 983 984 //////////////////////////////////////////////////////////////////////////////////// 984 985 // This function is executed in parallel by all processors P[x][y][0]. 985 // It initialises all schedulers in cluster[x][y]. The MMU must be activated.986 // P[x][y][0] initialises all schedulers in cluster[x][y]. The MMU must be activated. 986 987 // It is split in two phases separated by a synchronisation barrier. 987 // - In Step 1, it initialises the _schedulers[x][y][ l] pointers array, the988 // idle_t askcontext, the HWI / PTI / WTI interrupt vectors,989 // and the CU HWI / PTI / WTI masks.990 // - In Step 2, it scan all t asks in all vspaces to complete the tasks contexts,988 // - In Step 1, it initialises the _schedulers[x][y][p] pointers array, the 989 // idle_thread context, the HWI / PTI / WTI interrupt vectors, 990 // and the XCU HWI / PTI / WTI masks. 991 // - In Step 2, it scan all threads in all vspaces to complete the threads contexts, 991 992 // initialisation as specified in the mapping_info data structure, 992 993 // and set the CP0_SCHED register. … … 999 1000 mapping_vspace_t* vspace = _get_vspace_base(header); 1000 1001 mapping_vseg_t* vseg = _get_vseg_base(header); 1001 mapping_t ask_t* task = _get_task_base(header);1002 mapping_thread_t* thread = _get_thread_base(header); 1002 1003 mapping_periph_t* periph = _get_periph_base(header); 1003 1004 mapping_irq_t* irq = _get_irq_base(header); … … 1007 1008 unsigned int vspace_id; 1008 1009 unsigned int vseg_id; 1009 unsigned int t ask_id;1010 unsigned int thread_id; 1010 1011 1011 1012 unsigned int sched_vbase; // schedulers array vbase address … … 1026 1027 //////////////////////////////////////////////////////////////////////////////// 1027 1028 // Step 1 : - initialize the schedulers[] array of pointers, 1028 // - initialize the "t asks" and "current variables.1029 // - initialise the idle taskcontext.1029 // - initialize the "threads" and "current variables. 1030 // - initialise the idle_thread context. 1030 1031 // - initialize the HWI, PTI and WTI interrupt vectors. 1031 1032 // - initialize the XCU masks for HWI / WTI / PTI interrupts. … … 1056 1057 _schedulers[x][y][lpid] = psched; 1057 1058 1058 // initialise the "t asks" and "current" variables default values1059 psched->t asks= 0;1060 psched->current = IDLE_T ASK_INDEX;1059 // initialise the "threads" and "current" variables default values 1060 psched->threads = 0; 1061 psched->current = IDLE_THREAD_INDEX; 1061 1062 1062 1063 // set default values for HWI / PTI / SWI vectors (valid bit = 0) … … 1069 1070 } 1070 1071 1071 // initializes the idle_t askcontext:1072 // - the SR slot is 0xFF03 because this t askrun in kernel mode.1072 // initializes the idle_thread context: 1073 // - the SR slot is 0xFF03 because this thread run in kernel mode. 1073 1074 // - it uses the page table of vspace[0] 1074 // - it uses the kernel TTY terminal1075 // - it uses the kernel TTY0 terminal 1075 1076 // - slots containing addresses (SP,RA,EPC) are initialised by kernel_init() 1076 1077 psched->context[IDLE_TASK_INDEX][CTX_CR_ID] = 0; 1078 psched->context[IDLE_TASK_INDEX][CTX_SR_ID] = 0xFF03; 1079 psched->context[IDLE_TASK_INDEX][CTX_PTPR_ID] = _ptabs_paddr[0][x][y]>>13; 1080 psched->context[IDLE_TASK_INDEX][CTX_PTAB_ID] = _ptabs_vaddr[0][x][y]; 1081 psched->context[IDLE_TASK_INDEX][CTX_TTY_ID] = 0; 1082 psched->context[IDLE_TASK_INDEX][CTX_LTID_ID] = IDLE_TASK_INDEX; 1083 psched->context[IDLE_TASK_INDEX][CTX_VSID_ID] = 0; 1084 psched->context[IDLE_TASK_INDEX][CTX_NORUN_ID] = 0; 1085 psched->context[IDLE_TASK_INDEX][CTX_SIG_ID] = 0; 1077 // - It is always executable (NORUN == 0) 1078 1079 psched->context[IDLE_THREAD_INDEX].slot[CTX_CR_ID] = 0; 1080 psched->context[IDLE_THREAD_INDEX].slot[CTX_SR_ID] = 0xFF03; 1081 psched->context[IDLE_THREAD_INDEX].slot[CTX_PTPR_ID] = _ptabs_paddr[0][x][y]>>13; 1082 psched->context[IDLE_THREAD_INDEX].slot[CTX_PTAB_ID] = _ptabs_vaddr[0][x][y]; 1083 psched->context[IDLE_THREAD_INDEX].slot[CTX_TTY_ID] = 0; 1084 psched->context[IDLE_THREAD_INDEX].slot[CTX_LTID_ID] = IDLE_THREAD_INDEX; 1085 psched->context[IDLE_THREAD_INDEX].slot[CTX_VSID_ID] = 0; 1086 psched->context[IDLE_THREAD_INDEX].slot[CTX_NORUN_ID] = 0; 1087 psched->context[IDLE_THREAD_INDEX].slot[CTX_SIGS_ID] = 0; 1088 psched->context[IDLE_THREAD_INDEX].slot[CTX_LOCKS_ID] = 0; 1086 1089 } 1087 1090 … … 1213 1216 1214 1217 /////////////////////////////////////////////////////////////////////////////// 1215 // Step 2 : Initialise the t asks context. The context of taskplaced1218 // Step 2 : Initialise the threads context. The context of a thread placed 1216 1219 // on processor P must be stored in the scheduler of P. 1217 // This require two nested loops: loop on the tasks, and loop 1218 // on the local processors. We complete the scheduler when the 1219 // required placement fit one local processor. 1220 // For each vspace, this require two nested loops: loop on the threads, 1221 // and loop on the local processors in cluster[x,y]. 1222 // We complete the scheduler when the required placement matches 1223 // the local processor. 1220 1224 /////////////////////////////////////////////////////////////////////////////// 1221 1225 … … 1226 1230 _set_mmu_ptpr( (unsigned int)(_ptabs_paddr[vspace_id][x][y] >> 13) ); 1227 1231 1228 // ctx_norun depends on the vspace active field 1229 unsigned int ctx_norun = (vspace[vspace_id].active == 0); 1230 1231 // loop on the tasks in vspace (task_id is the global index in mapping) 1232 for (task_id = vspace[vspace_id].task_offset; 1233 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 1234 task_id++) 1235 { 1236 // get the required task placement coordinates [x,y,p] 1237 unsigned int req_x = cluster[task[task_id].clusterid].x; 1238 unsigned int req_y = cluster[task[task_id].clusterid].y; 1239 unsigned int req_p = task[task_id].proclocid; 1232 // loop on the threads in vspace (thread_id is the global index in mapping) 1233 for (thread_id = vspace[vspace_id].thread_offset; 1234 thread_id < (vspace[vspace_id].thread_offset + vspace[vspace_id].threads); 1235 thread_id++) 1236 { 1237 // get the required thread placement coordinates [x,y,p] 1238 unsigned int req_x = cluster[thread[thread_id].clusterid].x; 1239 unsigned int req_y = cluster[thread[thread_id].clusterid].y; 1240 unsigned int req_p = thread[thread_id].proclocid; 1241 1242 // ctx_norun : two conditions to activate a thread 1243 // - The vspace.active flag is set in the mapping 1244 // - The thread.is_main flag is set in the mapping 1245 unsigned int ctx_norun = (unsigned int)(vspace[vspace_id].active == 0) | 1246 (unsigned int)(thread[thread_id].is_main == 0); 1240 1247 1241 1248 // ctx_ptpr : page table physical base address (shifted by 13 bit) … … 1246 1253 1247 1254 // ctx_entry : Get the virtual address of the memory location containing 1248 // the t askentry point : the start_vector is stored by GCC in the1249 // seg_data segment, and we must wait the .elf loading to get1255 // the thread entry point : the start_vector is stored by GCC in the 1256 // seg_data segment, and we must wait the application.elf loading to get 1250 1257 // the entry point value... 1251 1258 vseg_id = vspace[vspace_id].start_vseg_id; 1252 unsigned int ctx_entry = vseg[vseg_id].vbase + (t ask[task_id].startid)*4;1259 unsigned int ctx_entry = vseg[vseg_id].vbase + (thread[thread_id].startid)*4; 1253 1260 1254 1261 // ctx_sp : Get the vseg containing the stack 1255 vseg_id = task[task_id].stack_vseg_id; 1256 unsigned int ctx_sp = vseg[vseg_id].vbase + vseg[vseg_id].length; 1257 1258 // get vspace thread index 1259 unsigned int thread_id = task[task_id].trdid; 1262 // allocate 16 slots (64 bytes) for possible arguments. 1263 vseg_id = thread[thread_id].stack_vseg_id; 1264 unsigned int ctx_sp = vseg[vseg_id].vbase + vseg[vseg_id].length - 64; 1260 1265 1261 1266 // loop on the local processors … … 1267 1272 psched = _schedulers[x][y][lpid]; 1268 1273 1269 // get local task index in scheduler 1270 unsigned int ltid = psched->tasks; 1271 1272 // update the "tasks" field in scheduler: 1273 psched->tasks = ltid + 1; 1274 1275 // initializes the task context 1276 psched->context[ltid][CTX_CR_ID] = 0; 1277 psched->context[ltid][CTX_SR_ID] = GIET_SR_INIT_VALUE; 1278 psched->context[ltid][CTX_SP_ID] = ctx_sp; 1279 psched->context[ltid][CTX_EPC_ID] = ctx_entry; 1280 psched->context[ltid][CTX_ENTRY_ID] = ctx_entry; 1281 psched->context[ltid][CTX_PTPR_ID] = ctx_ptpr; 1282 psched->context[ltid][CTX_PTAB_ID] = ctx_ptab; 1283 psched->context[ltid][CTX_LTID_ID] = ltid; 1284 psched->context[ltid][CTX_GTID_ID] = task_id; 1285 psched->context[ltid][CTX_TRDID_ID] = thread_id; 1286 psched->context[ltid][CTX_VSID_ID] = vspace_id; 1287 psched->context[ltid][CTX_NORUN_ID] = ctx_norun; 1288 psched->context[ltid][CTX_SIG_ID] = 0; 1289 1290 psched->context[ltid][CTX_TTY_ID] = 0xFFFFFFFF; 1291 psched->context[ltid][CTX_CMA_FB_ID] = 0xFFFFFFFF; 1292 psched->context[ltid][CTX_CMA_RX_ID] = 0xFFFFFFFF; 1293 psched->context[ltid][CTX_CMA_TX_ID] = 0xFFFFFFFF; 1294 psched->context[ltid][CTX_NIC_RX_ID] = 0xFFFFFFFF; 1295 psched->context[ltid][CTX_NIC_TX_ID] = 0xFFFFFFFF; 1296 psched->context[ltid][CTX_TIM_ID] = 0xFFFFFFFF; 1297 psched->context[ltid][CTX_HBA_ID] = 0xFFFFFFFF; 1298 1299 // update task ltid field in the mapping 1300 task[task_id].ltid = ltid; 1274 // ltid : compute local thread index in scheduler 1275 unsigned int ltid = psched->threads; 1276 1277 // update the threads field in scheduler: 1278 psched->threads = ltid + 1; 1279 1280 // ctx_trd_id : compute pthread global identifier 1281 unsigned int ctx_trdid = x << 24 | y<<16 | lpid<<8 | ltid; 1282 1283 // initializes the thread context 1284 psched->context[ltid].slot[CTX_CR_ID] = 0; 1285 psched->context[ltid].slot[CTX_SR_ID] = GIET_SR_INIT_VALUE; 1286 psched->context[ltid].slot[CTX_SP_ID] = ctx_sp; 1287 psched->context[ltid].slot[CTX_EPC_ID] = ctx_entry; 1288 psched->context[ltid].slot[CTX_ENTRY_ID] = ctx_entry; 1289 psched->context[ltid].slot[CTX_PTPR_ID] = ctx_ptpr; 1290 psched->context[ltid].slot[CTX_PTAB_ID] = ctx_ptab; 1291 psched->context[ltid].slot[CTX_LTID_ID] = ltid; 1292 psched->context[ltid].slot[CTX_TRDID_ID] = ctx_trdid; 1293 psched->context[ltid].slot[CTX_VSID_ID] = vspace_id; 1294 psched->context[ltid].slot[CTX_NORUN_ID] = ctx_norun; 1295 psched->context[ltid].slot[CTX_SIGS_ID] = 0; 1296 psched->context[ltid].slot[CTX_LOCKS_ID] = 0; 1297 1298 psched->context[ltid].slot[CTX_TTY_ID] = 0xFFFFFFFF; 1299 psched->context[ltid].slot[CTX_CMA_FB_ID] = 0xFFFFFFFF; 1300 psched->context[ltid].slot[CTX_CMA_RX_ID] = 0xFFFFFFFF; 1301 psched->context[ltid].slot[CTX_CMA_TX_ID] = 0xFFFFFFFF; 1302 psched->context[ltid].slot[CTX_NIC_RX_ID] = 0xFFFFFFFF; 1303 psched->context[ltid].slot[CTX_NIC_TX_ID] = 0xFFFFFFFF; 1304 psched->context[ltid].slot[CTX_TIM_ID] = 0xFFFFFFFF; 1305 psched->context[ltid].slot[CTX_HBA_ID] = 0xFFFFFFFF; 1306 1307 // update thread ltid field in the mapping 1308 thread[thread_id].ltid = ltid; 1301 1309 1302 1310 #if BOOT_DEBUG_SCHED 1303 _printf("\nT ask%s in vspace %s allocated to P[%d,%d,%d]\n"1311 _printf("\nThread %s in vspace %s allocated to P[%d,%d,%d]\n" 1304 1312 " - ctx[LTID] = %d\n" 1313 " - ctx[TRDID] = %d\n" 1305 1314 " - ctx[SR] = %x\n" 1306 1315 " - ctx[SP] = %x\n" … … 1309 1318 " - ctx[PTAB] = %x\n" 1310 1319 " - ctx[VSID] = %d\n" 1311 " - ctx[TRDID] = %d\n"1312 1320 " - ctx[NORUN] = %x\n" 1313 1321 " - ctx[SIG] = %x\n", 1314 t ask[task_id].name,1322 thread[thread_id].name, 1315 1323 vspace[vspace_id].name, 1316 1324 x, y, lpid, 1317 psched->context[ltid] [CTX_LTID_ID],1318 psched->context[ltid] [CTX_SR_ID],1319 psched->context[ltid] [CTX_SP_ID],1320 psched->context[ltid] [CTX_ENTRY_ID],1321 psched->context[ltid] [CTX_PTPR_ID],1322 psched->context[ltid] [CTX_PTAB_ID],1323 psched->context[ltid] [CTX_VSID_ID],1324 psched->context[ltid] [CTX_TRDID_ID],1325 psched->context[ltid] [CTX_NORUN_ID],1326 psched->context[ltid] [CTX_SIG_ID] );1325 psched->context[ltid].slot[CTX_LTID_ID], 1326 psched->context[ltid].slot[CTX_TRDID_ID], 1327 psched->context[ltid].slot[CTX_SR_ID], 1328 psched->context[ltid].slot[CTX_SP_ID], 1329 psched->context[ltid].slot[CTX_ENTRY_ID], 1330 psched->context[ltid].slot[CTX_PTPR_ID], 1331 psched->context[ltid].slot[CTX_PTAB_ID], 1332 psched->context[ltid].slot[CTX_VSID_ID], 1333 psched->context[ltid].slot[CTX_NORUN_ID], 1334 psched->context[ltid].slot[CTX_SIG_ID] ); 1327 1335 #endif 1328 1336 } // end if FIT 1329 1337 } // end for loop on local procs 1330 } // end loop on t asks1338 } // end loop on threads 1331 1339 } // end loop on vspaces 1332 1340 } // end boot_scheduler_init() … … 1544 1552 " check that all global variables are in data segment\n", 1545 1553 seg_vaddr, pathname , seg_memsz , seg_filesz ); 1546 _exit();1554 _exit(); 1547 1555 } 1548 1556 -
soft/giet_vm/giet_common/kernel_locks.c
r632 r709 70 70 : "r" (ptr), "r" (mask) 71 71 : "$10", "$11", "$12", "memory" ); 72 } 73 74 ///////////////////////////////////////////////////// 75 unsigned int _atomic_test_and_set( unsigned int* ptr, 76 unsigned int value ) 77 { 78 unsigned int ret = 1; 79 80 asm volatile ( 81 "ori %0, $0, 1 \n" /* default : ret <= 1 */ 82 "move $10, %1 \n" /* $10 <= ptr */ 83 "move $11, %2 \n" /* $11 <= value */ 84 "ll $12, 0($10) \n" /* $12 <= *ptr */ 85 "bne $12, $0, 1515f \n" /* return 1 if non zero */ 86 "sc $11, 0($10) \n" /* *ptr <= $12 */ 87 "beqz $11, 1515f \n" /* return 1 if failure */ 88 "ori %0, $0, 0 \n" /* success : ret <= 0 */ 89 "1515: \n" 90 : "=r" (ret) 91 : "r" (ptr), "r" (value) 92 : "$10", "$11", "$12", "memory" ); 93 94 return ret; 72 95 } 73 96 -
soft/giet_vm/giet_common/kernel_locks.h
r632 r709 20 20 21 21 extern unsigned int _atomic_increment( unsigned int* ptr, 22 int increment );22 int increment ); 23 23 24 24 extern void _atomic_or( unsigned int* ptr, … … 27 27 extern void _atomic_and( unsigned int* ptr, 28 28 unsigned int mask ); 29 30 extern unsigned int _atomic_test_and_set( unsigned int* ptr, 31 unsigned int value ); 29 32 30 33 ////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_common/mips32_registers.h
r399 r709 1 1 /********************************************************************************/ 2 /* File : mips32_registers.h */3 /* Author : Alain Greiner */4 /* Date : 26/03/2012 */2 /* File : mips32_registers.h */ 3 /* Author : Alain Greiner */ 4 /* Date : 26/03/2012 */ 5 5 /********************************************************************************/ 6 /* We define mnemonics for MIPS32 registers */6 /* We define mnemonics for MIPS32 registers */ 7 7 /********************************************************************************/ 8 8 -
soft/giet_vm/giet_common/tty0.c
r594 r709 12 12 #include <stdarg.h> 13 13 #include <tty_driver.h> 14 #include <ctx_handler.h> 14 15 #include <utils.h> 15 16 #include <kernel_locks.h> … … 30 31 spin_lock_t _tty0_spin_lock __attribute__((aligned(64))); 31 32 32 ////////////////////////////////////////////// 33 unsigned int _tty0_write( char* buffer, 34 unsigned int nbytes ) 33 ///////////////////////////////////////////////////// 34 unsigned int _tty_channel_write( unsigned int channel, 35 char* buffer, 36 unsigned int nbytes ) 35 37 { 36 38 unsigned int n; … … 40 42 { 41 43 // test TTY_TX buffer full 42 if ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) ) // buffer full44 if ( (_tty_get_register( channel , TTY_STATUS ) & 0x2) ) // buffer full 43 45 { 44 46 // retry if full 45 47 for( k = 0 ; k < 10000 ; k++ ) 46 48 { 47 if ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) == 0) break;49 if ( (_tty_get_register( channel , TTY_STATUS ) & 0x2) == 0) break; 48 50 } 49 51 // return error if full after 10000 retry … … 52 54 53 55 // write one byte 54 if (buffer[n] == '\n') _tty_set_register( 0, TTY_WRITE, (unsigned int)'\r' );55 _tty_set_register( 0, TTY_WRITE, (unsigned int)buffer[n] );56 if (buffer[n] == '\n') _tty_set_register( channel, TTY_WRITE, (unsigned int)'\r' ); 57 _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[n] ); 56 58 } 57 59 return 0; … … 65 67 while ( string[n] > 0 ) n++; 66 68 67 _tty 0_write(string, n );69 _tty_channel_write( 0, string, n ); 68 70 } 69 71 … … 84 86 val = val >> 4; 85 87 } 86 _tty 0_write(buf, 10 );88 _tty_channel_write( 0, buf, 10 ); 87 89 } 88 90 … … 102 104 val = val >> 4; 103 105 } 104 _tty 0_write(buf, 18 );106 _tty_channel_write( 0, buf, 18 ); 105 107 } 106 108 … … 126 128 val /= 10; 127 129 } 128 _tty 0_write(&buf[first], 10 - first );130 _tty_channel_write( 0, &buf[first], 10 - first ); 129 131 } 130 132 … … 140 142 141 143 ////////////////////////////////////////////////////////// 142 static void _kernel_printf( char * format, va_list* args ) 144 static void _kernel_printf( unsigned int channel, 145 char * format, 146 va_list* args ) 143 147 { 144 148 … … 151 155 if (i) 152 156 { 153 if ( _tty 0_write(format, i ) ) goto return_error;157 if ( _tty_channel_write( channel, format, i ) ) goto return_error; 154 158 format += i; 155 159 } … … 188 192 { 189 193 val = -val; 190 if ( _tty 0_write("-" , 1 ) ) goto return_error;194 if ( _tty_channel_write( channel, "-" , 1 ) ) goto return_error; 191 195 } 192 196 for(i = 0; i < 10; i++) … … 214 218 { 215 219 unsigned int val = va_arg( *args , unsigned int ); 216 if ( _tty 0_write("0x" , 2 ) ) goto return_error;220 if ( _tty_channel_write( channel, "0x" , 2 ) ) goto return_error; 217 221 for(i = 0; i < 8; i++) 218 222 { … … 227 231 { 228 232 unsigned int val = va_arg( *args , unsigned int ); 229 if ( _tty 0_write("0x" , 2 ) ) goto return_error;233 if ( _tty_channel_write( channel, "0x" , 2 ) ) goto return_error; 230 234 for(i = 0; i < 8; i++) 231 235 { … … 240 244 { 241 245 unsigned long long val = va_arg( *args , unsigned long long ); 242 if ( _tty 0_write("0x" , 2 ) ) goto return_error;246 if ( _tty_channel_write( channel, "0x" , 2 ) ) goto return_error; 243 247 for(i = 0; i < 16; i++) 244 248 { … … 264 268 } 265 269 266 if ( _tty 0_write(pbuf, len ) ) goto return_error;270 if ( _tty_channel_write( channel, pbuf, len ) ) goto return_error; 267 271 268 272 goto printf_text; … … 284 288 _putd( lpid ); 285 289 _puts("]\n"); 286 287 290 _exit(); 288 291 } … … 294 297 va_list args; 295 298 299 // call kernel_printf 296 300 va_start( args , format ); 297 _kernel_printf( format , &args );301 _kernel_printf( 0, format , &args ); 298 302 va_end( args ); 299 303 } 304 300 305 //////////////////////////////// 301 306 void _printf( char* format, ...) … … 309 314 else _sqt_lock_acquire( &_tty0_sqt_lock ); 310 315 316 // call kernel_printf 311 317 va_start( args , format ); 312 _kernel_printf( format , &args );318 _kernel_printf( 0, format , &args ); 313 319 va_end( args ); 314 320 … … 318 324 _it_restore( &save_sr ); 319 325 } 326 327 ///////////////////////////////////// 328 void _user_printf( char* format, ...) 329 { 330 va_list args; 331 332 // get calling thread TYY channel 333 unsigned int channel = _get_context_slot( CTX_TTY_ID ); 334 if( channel >= NB_TTY_CHANNELS ) 335 { 336 _puts("\n[GIET ERROR] in _user_printf() : no TTY allocated for thread "); 337 _putx( _get_thread_trdid() ); 338 _puts("\n"); 339 _exit(); 340 } 341 342 // call kernel_printf 343 va_start( args , format ); 344 _kernel_printf( channel, format , &args ); 345 va_end( args ); 346 } 347 320 348 321 349 -
soft/giet_vm/giet_common/tty0.h
r466 r709 14 14 15 15 /////////////////////////////////////////////////////////////////////////////////// 16 // Access functions to kernel terminal TTY0 16 // Access functions to kernel terminal TTY0 (or calling thread TTY) 17 17 /////////////////////////////////////////////////////////////////////////////////// 18 18 … … 27 27 extern void _getc( char* byte ); 28 28 29 extern void _printf( char* format, ... ); 30 29 31 extern void _nolock_printf( char* format, ... ); 30 32 31 extern void _ printf( char* format, ... );33 extern void _user_printf( char* format, ... ); 32 34 33 35 #endif -
soft/giet_vm/giet_common/utils.c
r618 r709 16 16 #include <ctx_handler.h> 17 17 18 // This variable is allocated in theboot.c file or in kernel_init.c file19 extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];18 // This variable is allocated in boot.c file or in kernel_init.c file 19 extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 20 20 21 21 /////////////////////////////////////////////////////////////////////////// … … 23 23 /////////////////////////////////////////////////////////////////////////// 24 24 25 ///////////////////////// 26 unsigned int_get_sched()25 //////////////////////////////// 26 static_scheduler_t* _get_sched() 27 27 { 28 28 unsigned int ret; 29 29 asm volatile( "mfc0 %0, $4,2 \n" 30 30 : "=r"(ret) ); 31 return ret; 31 32 return (static_scheduler_t*)ret; 32 33 } 33 34 /////////////////////// … … 411 412 412 413 //////////////////////////////////////////////////////////////////////////// 413 // Scheduler and t asks context access functions414 // Scheduler and threads context access functions 414 415 //////////////////////////////////////////////////////////////////////////// 415 416 416 417 417 /////////////////////////////////// 418 unsigned int _get_current_task_id() 419 { 420 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 421 return (unsigned int) (psched->current); 418 /////////////////////////////// 419 unsigned int _get_thread_ltid() 420 { 421 static_scheduler_t* psched = (static_scheduler_t *) _get_sched(); 422 return psched->current; 423 } 424 425 //////////////////////////////// 426 unsigned int _get_thread_trdid() 427 { 428 static_scheduler_t* psched = (static_scheduler_t *) _get_sched(); 429 unsigned int current = psched->current; 430 return psched->context[current].slot[CTX_TRDID_ID]; 431 } 432 433 ////////////////////////////////////////////// 434 unsigned int _get_thread_slot( unsigned int x, 435 unsigned int y, 436 unsigned int p, 437 unsigned int ltid, 438 unsigned int slotid ) 439 { 440 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 441 return psched->context[ltid].slot[slotid]; 442 } 443 444 ////////////////////////////////////// 445 void _set_thread_slot( unsigned int x, 446 unsigned int y, 447 unsigned int p, 448 unsigned int ltid, 449 unsigned int slotid, 450 unsigned int value ) 451 { 452 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 453 psched->context[ltid].slot[slotid] = value; 454 } 455 456 ///////////////////////////////////////////////////// 457 unsigned int _get_context_slot( unsigned int slotid ) 458 { 459 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 460 unsigned int ltid = psched->current; 461 return psched->context[ltid].slot[slotid]; 422 462 } 423 463 424 464 //////////////////////////////////////////// 425 unsigned int _get_task_slot( unsigned int x, 426 unsigned int y, 427 unsigned int p, 428 unsigned int ltid, 429 unsigned int slot ) 430 { 431 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 432 return psched->context[ltid][slot]; 433 } 434 435 //////////////////////////////////// 436 void _set_task_slot( unsigned int x, 437 unsigned int y, 438 unsigned int p, 439 unsigned int ltid, 440 unsigned int slot, 441 unsigned int value ) 442 { 443 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 444 psched->context[ltid][slot] = value; 445 } 446 447 /////////////////////////////////////////////////// 448 unsigned int _get_context_slot( unsigned int slot ) 465 void _set_context_slot( unsigned int slotid, 466 unsigned int value ) 449 467 { 450 468 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 451 unsigned int task_id = psched->current; 452 return psched->context[task_id][slot]; 453 } 454 455 /////////////////////////////////////////// 456 void _set_context_slot( unsigned int slot, 457 unsigned int value ) 458 { 459 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 460 unsigned int task_id = psched->current; 461 psched->context[task_id][slot] = value; 469 unsigned int ltid = psched->current; 470 psched->context[ltid].slot[slotid] = value; 462 471 } 463 472 … … 496 505 MAPPING_VSPACE_SIZE * header->vspaces); 497 506 } 498 ////////////////////////////////////////////////////////// 499 mapping_t ask_t * _get_task_base(mapping_header_t * header)500 { 501 return (mapping_t ask_t *) ((char *) header +507 ////////////////////////////////////////////////////////////// 508 mapping_thread_t * _get_thread_base(mapping_header_t * header) 509 { 510 return (mapping_thread_t *) ((char *) header + 502 511 MAPPING_HEADER_SIZE + 503 512 MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE + … … 515 524 MAPPING_VSPACE_SIZE * header->vspaces + 516 525 MAPPING_VSEG_SIZE * header->vsegs + 517 MAPPING_T ASK_SIZE * header->tasks);526 MAPPING_THREAD_SIZE * header->threads); 518 527 } 519 528 /////////////////////////////////////////////////////// … … 526 535 MAPPING_VSPACE_SIZE * header->vspaces + 527 536 MAPPING_VSEG_SIZE * header->vsegs + 528 MAPPING_T ASK_SIZE * header->tasks +537 MAPPING_THREAD_SIZE * header->threads + 529 538 MAPPING_PROC_SIZE * header->procs); 530 539 } … … 538 547 MAPPING_VSPACE_SIZE * header->vspaces + 539 548 MAPPING_VSEG_SIZE * header->vsegs + 540 MAPPING_T ASK_SIZE * header->tasks +549 MAPPING_THREAD_SIZE * header->threads + 541 550 MAPPING_PROC_SIZE * header->procs + 542 551 MAPPING_IRQ_SIZE * header->irqs); -
soft/giet_vm/giet_common/utils.h
r618 r709 14 14 15 15 #include <mapping_info.h> 16 #include <ctx_handler.h> 16 17 17 18 ////////////////////////////////////////////////////////////////////////////////// … … 41 42 /////////////////////////////////////////////////////////////////////////// 42 43 43 extern unsigned int_get_sched(void);44 extern static_scheduler_t* _get_sched(void); 44 45 45 46 extern unsigned int _get_epc(void); … … 105 106 106 107 /////////////////////////////////////////////////////////////////////////// 107 // Scheduler and t askcontext access functions108 // Scheduler and thread context access functions 108 109 /////////////////////////////////////////////////////////////////////////// 109 110 110 extern unsigned int _get_ current_task_id(void);111 extern unsigned int _get_thread_ltid(void); 111 112 112 extern unsigned int _get_task_slot( unsigned int x, 113 unsigned int y, 114 unsigned int p, 115 unsigned int ltid, 116 unsigned int slot ); 113 extern unsigned int _get_thread_trdid(void); 117 114 118 extern void _set_task_slot( unsigned int x, 119 unsigned int y, 120 unsigned int p, 121 unsigned int ltid, 122 unsigned int slot, 123 unsigned int value ); 115 extern unsigned int _get_thread_slot( unsigned int x, 116 unsigned int y, 117 unsigned int p, 118 unsigned int ltid, 119 unsigned int slot ); 120 121 extern void _set_thread_slot( unsigned int x, 122 unsigned int y, 123 unsigned int p, 124 unsigned int ltid, 125 unsigned int slot, 126 unsigned int value ); 124 127 125 128 extern unsigned int _get_context_slot( unsigned int slot ); … … 136 139 extern mapping_vspace_t * _get_vspace_base(mapping_header_t* header); 137 140 extern mapping_vseg_t * _get_vseg_base(mapping_header_t* header); 138 extern mapping_t ask_t * _get_task_base(mapping_header_t* header);141 extern mapping_thread_t * _get_thread_base(mapping_header_t* header); 139 142 extern mapping_proc_t * _get_proc_base(mapping_header_t* header); 140 143 extern mapping_irq_t * _get_irq_base(mapping_header_t* header); -
soft/giet_vm/giet_config.h
r649 r709 37 37 #define GIET_DEBUG_FBF_CMA 0 /* FBF_CMA access */ 38 38 #define GIET_DEBUG_COPROC 0 /* coprocessor access */ 39 #define GIET_DEBUG_EXEC 0 /* kill/exec mechanism*/39 #define GIET_DEBUG_EXEC 1 /* kill/exec & thread control */ 40 40 41 41 #define GIET_DEBUG_USER_MALLOC 0 /* malloc library */ … … 49 49 50 50 #define GIET_ELF_BUFFER_SIZE 0x80000 /* buffer for .elf files */ 51 #define GIET_IDLE_T ASK_PERIOD0x10000000 /* Idle Task message period */51 #define GIET_IDLE_THREAD_PERIOD 0x10000000 /* Idle Task message period */ 52 52 #define GIET_OPEN_FILES_MAX 16 /* max simultaneously open files */ 53 53 #define GIET_NB_VSPACE_MAX 16 /* max number of virtual spaces */ -
soft/giet_vm/giet_drivers/bdv_driver.c
r657 r709 37 37 spin_lock_t _bdv_lock __attribute__((aligned(64))); 38 38 39 // global index of the waiting t ask(only used in descheduling mode)39 // global index of the waiting thread (only used in descheduling mode) 40 40 __attribute__((section(".kdata"))) 41 unsigned int _bdv_ gtid;41 unsigned int _bdv_trdid; 42 42 43 43 // BDV peripheral status (only used in descheduling mode) … … 75 75 unsigned int count) 76 76 { 77 unsigned int procid = _get_procid(); 78 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 79 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH) - 1);80 unsigned int p = procid & ((1<<P_WIDTH)-1);81 82 #if GIET_DEBUG_IOC 77 78 #if GIET_DEBUG_IOC 79 unsigned int procid = _get_procid(); 80 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 81 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH) - 1); 82 unsigned int p = procid & ((1<<P_WIDTH)-1); 83 83 if ( _get_proctime() > GIET_DEBUG_IOC ) 84 84 _printf("\n[BDV DEBUG] P[%d,%d,%d] enters _bdv_access at cycle %d\n" … … 97 97 unsigned int status; 98 98 99 // get the lock protecting BDV 99 // get the BDV lock and register it in task context 100 static_scheduler_t* psched = _get_sched(); 101 unsigned int ltid = _get_thread_ltid(); 100 102 _spin_lock_acquire( &_bdv_lock ); 103 _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_BDV ); 101 104 102 105 // set device registers … … 149 152 150 153 ///////////////////////////////////////////////////////////////// 151 // in descheduling mode, we deschedule the t ask152 // and use an interrupt to reschedule the t ask.154 // in descheduling mode, we deschedule the thread 155 // and use an interrupt to reschedule the thread. 153 156 // We need a critical section, because we must reset the RUN bit 154 157 // before to launch the transfer, and we don't want to be … … 158 161 { 159 162 unsigned int save_sr; 160 unsigned int ltid = _get_current_task_id();161 163 162 164 // activates BDV interrupt 163 165 _bdv_set_register( BLOCK_DEVICE_IRQ_ENABLE, 1 ); 164 166 165 // set _bdv_ gtid166 _bdv_ gtid = (procid<<16) + ltid;167 // set _bdv_trdid 168 _bdv_trdid = _get_thread_trdid(); 167 169 168 170 // enters critical section … … 170 172 171 173 // Set NORUN_MASK_IOC bit 172 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 173 _atomic_or( &psched->context[ltid][CTX_NORUN_ID] , NORUN_MASK_IOC ); 174 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 175 unsigned int ltid = psched->current; 176 _atomic_or( &psched->context[ltid].slot[CTX_NORUN_ID] , NORUN_MASK_IOC ); 174 177 175 178 // launch transfer … … 184 187 #endif 185 188 186 // deschedule t ask189 // deschedule thread 187 190 _ctx_switch(); 188 191 … … 201 204 } 202 205 203 // release lock206 // release BDV lock and clear task context 204 207 _spin_lock_release( &_bdv_lock ); 208 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_BDV ); 205 209 206 210 #if GIET_DEBUG_IOC … … 241 245 _bdv_status = status; 242 246 243 // identify task waiting on BDV 244 unsigned int procid = _bdv_gtid>>16; 245 unsigned int ltid = _bdv_gtid & 0xFFFF; 246 unsigned int cluster = procid >> P_WIDTH; 247 unsigned int x = cluster >> Y_WIDTH; 248 unsigned int y = cluster & ((1<<Y_WIDTH)-1); 249 unsigned int p = procid & ((1<<P_WIDTH)-1); 247 // identify thread waiting on BDV 248 unsigned int x = (_bdv_trdid >> 24) & 0xFF; 249 unsigned int y = (_bdv_trdid >> 16) & 0xFF; 250 unsigned int p = (_bdv_trdid >> 8) & 0xFF; 251 unsigned int ltid = (_bdv_trdid ) & 0xFF; 250 252 251 253 // Reset NORUN_MASK_IOC bit 252 254 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 253 unsigned int* ptr = &psched->context[ltid] [CTX_NORUN_ID];255 unsigned int* ptr = &psched->context[ltid].slot[CTX_NORUN_ID]; 254 256 _atomic_and( ptr , ~NORUN_MASK_IOC ); 255 257 256 // send a WAKUP WTI to processor running the sleeping t ask257 _xcu_send_wti( cluster,258 // send a WAKUP WTI to processor running the sleeping thread 259 _xcu_send_wti( (x<<Y_WIDTH) + y, 258 260 p, 259 261 0 ); // don't force context switch … … 266 268 if ( _get_proctime() > GIET_DEBUG_IOC ) 267 269 _printf("\n[BDV DEBUG] Processor[%d,%d,%d] enters _bdv_isr() at cycle %d\n" 268 " for t ask%d running on P[%d,%d,%d] / bdv_status = %x\n",270 " for thread %d running on P[%d,%d,%d] / bdv_status = %x\n", 269 271 c_x , c_y , c_p , _get_proctime() , 270 272 ltid , x , y , p , status ); -
soft/giet_vm/giet_drivers/bdv_driver.h
r529 r709 78 78 79 79 /////////////////////////////////////////////////////////////////////////////////// 80 // Access functions80 // Low level access function 81 81 /////////////////////////////////////////////////////////////////////////////////// 82 83 unsigned int _bdv_get_register( unsigned int index ); 84 85 void _bdv_set_register( unsigned int index, 86 unsigned int value ); 82 87 83 88 /////////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_drivers/hba_driver.c
r657 r709 46 46 sqt_lock_t _hba_allocator_lock __attribute__((aligned(64))); 47 47 48 // state of each slot (allocated to a t askor not)48 // state of each slot (allocated to a thread or not) 49 49 // access must be protected by the allocator_lock in descheduling mode 50 50 __attribute__((section(".kdata"))) … … 56 56 unsigned int _hba_active_cmd[32]; 57 57 58 // global index of the t ask, for each entry in the command list59 __attribute__((section(".kdata"))) 60 unsigned int _hba_ gtid[32];58 // global index of the thread, for each entry in the command list 59 __attribute__((section(".kdata"))) 60 unsigned int _hba_trid[32]; 61 61 62 62 // status of HBA commands … … 97 97 98 98 /////////////////////////////////////////////////////////////////////////////// 99 // This blocking fonction allocates a free command index to the t ask.99 // This blocking fonction allocates a free command index to the thread. 100 100 // The hba_allocator_lock is not used in boot mode. 101 101 // It returns the allocated command index (between 0 and 31) … … 132 132 /////////////////////////////////////////////////////////////////////////////// 133 133 // This function releases the command index in the hba_allocated_cmd table. 134 // There is no need to take the lock because only the t askwhich owns the134 // There is no need to take the lock because only the thread which owns the 135 135 // command can release it. 136 136 // return 0 if success, -1 if error … … 281 281 282 282 ///////////////////////////////////////////////////////////////// 283 // in descheduling mode, we deschedule the t ask284 // and use an interrupt to reschedule the t ask.283 // in descheduling mode, we deschedule the thread 284 // and use an interrupt to reschedule the thread. 285 285 // We need a critical section, because we must set the NORUN bit 286 286 // before to launch the transfer, and we don't want to be … … 297 297 #endif 298 298 unsigned int save_sr; 299 unsigned int ltid = _get_ current_task_id();299 unsigned int ltid = _get_thread_ltid(); 300 300 301 301 // activates HBA interrupts 302 302 _hba_set_register( HBA_PXIE , 0x00000001 ); 303 303 304 // set _hba_ gtid[cmd_id]305 _hba_ gtid[cmd_id] = (procid<<16) + ltid;304 // set _hba_trid[cmd_id] 305 _hba_trid[cmd_id] = (x<<24) + (y<<16) + (p<<8) + ltid; 306 306 307 307 // enters critical section … … 310 310 // Set NORUN_MASK_IOC bit 311 311 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 312 unsigned int* ptr = &psched->context[ltid] [CTX_NORUN_ID];312 unsigned int* ptr = &psched->context[ltid].slot[CTX_NORUN_ID]; 313 313 _atomic_or( ptr , NORUN_MASK_IOC ); 314 314 … … 319 319 _hba_active_cmd[cmd_id] = 1; 320 320 321 // deschedule t ask321 // deschedule thread 322 322 _ctx_switch(); 323 323 324 324 #if GIET_DEBUG_IOC 325 325 if (_get_proctime() > GIET_DEBUG_IOC) 326 _printf("\n[DEBUG HBA] _hba_access() : t ask%d on P[%d,%d,%d] resume at cycle %d\n",326 _printf("\n[DEBUG HBA] _hba_access() : thread %d on P[%d,%d,%d] resume at cycle %d\n", 327 327 ltid , x , y , p , _get_proctime() ); 328 328 #endif … … 438 438 _hba_active_cmd[cmd_id] = 0; 439 439 440 // identify waiting task 441 unsigned int procid = _hba_gtid[cmd_id]>>16; 442 unsigned int ltid = _hba_gtid[cmd_id] & 0xFFFF; 443 unsigned int cluster = procid >> P_WIDTH; 444 unsigned int x = cluster >> Y_WIDTH; 445 unsigned int y = cluster & ((1<<Y_WIDTH)-1); 446 unsigned int p = procid & ((1<<P_WIDTH)-1); 440 // identify waiting thread 441 unsigned int x = (_hba_trid[cmd_id]>>24) & 0xFF; 442 unsigned int y = (_hba_trid[cmd_id]>>16) & 0xFF; 443 unsigned int p = (_hba_trid[cmd_id]>> 8) & 0xFF; 444 unsigned int ltid = (_hba_trid[cmd_id] ) & 0xFF; 447 445 448 446 // Reset NORUN_MASK_IOC bit 449 447 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 450 _atomic_and( &psched->context[ltid] [CTX_NORUN_ID] , ~NORUN_MASK_IOC );451 452 // send a WAKUP WTI to processor running the waiting t ask453 _xcu_send_wti( cluster ,448 _atomic_and( &psched->context[ltid].slot[CTX_NORUN_ID] , ~NORUN_MASK_IOC ); 449 450 // send a WAKUP WTI to processor running the waiting thread 451 _xcu_send_wti( (x<<Y_WIDTH) + y, 454 452 p , 455 453 0 ); // don't force context switch … … 458 456 if (_get_proctime() > GIET_DEBUG_IOC) 459 457 _printf("\n[DEBUG HBA] _hba_isr() : command %d completed at cycle %d\n" 460 " resume t ask%d running on P[%d,%d,%d]\n",458 " resume thread %d running on P[%d,%d,%d]\n", 461 459 cmd_id , _get_proctime() , 462 460 ltid , x , y , p ); -
soft/giet_vm/giet_drivers/mwr_driver.c
r668 r709 74 74 unsigned int _coproc_error[X_SIZE*Y_SIZE]; 75 75 76 // descheduled t ask gtid (for MODE_DMA_IRQ)77 __attribute__((section(".kdata"))) 78 unsigned int _coproc_ gtid[X_SIZE*Y_SIZE];76 // descheduled thread trdid (for MODE_DMA_IRQ) 77 __attribute__((section(".kdata"))) 78 unsigned int _coproc_trdid[X_SIZE*Y_SIZE]; 79 79 80 80 ///////////////////////////////////////////////////////////////////////////// … … 205 205 _coproc_error[cluster_id] = error; 206 206 207 // identify task waiting on coprocessor completion 208 // this task can run in a remote cluster 209 unsigned int r_gtid = _coproc_gtid[cluster_id]; 210 unsigned int r_procid = r_gtid>>16; 211 unsigned int r_ltid = r_gtid & 0xFFFF; 212 unsigned int r_cluster = r_procid >> P_WIDTH; 213 unsigned int r_x = r_cluster >> Y_WIDTH; 214 unsigned int r_y = r_cluster & ((1<<Y_WIDTH)-1); 215 unsigned int r_p = r_procid & ((1<<P_WIDTH)-1); 207 // identify thread waiting on coprocessor completion (can run in a remote cluster) 208 unsigned int r_x = (_coproc_trdid[cluster_id]>>24) & 0xFF; 209 unsigned int r_y = (_coproc_trdid[cluster_id]>>16) & 0xFF; 210 unsigned int r_p = (_coproc_trdid[cluster_id]>> 8) & 0xFF; 211 unsigned int r_ltid = (_coproc_trdid[cluster_id] ) & 0xFF; 216 212 217 213 // Reset NORUN_MASK_IOC bit 218 214 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[r_x][r_y][r_p]; 219 unsigned int* ptr = &psched->context[r_ltid] [CTX_NORUN_ID];215 unsigned int* ptr = &psched->context[r_ltid].slot[CTX_NORUN_ID]; 220 216 _atomic_and( ptr , ~NORUN_MASK_COPROC ); 221 217 222 // send a WAKUP WTI to processor running the sleeping t ask223 _xcu_send_wti( r_cluster,218 // send a WAKUP WTI to processor running the sleeping thread 219 _xcu_send_wti( (r_x<<Y_WIDTH) + r_y, 224 220 r_p, 225 221 0 ); // don't force context switch … … 228 224 unsigned int p = gpid & ((1<<P_WIDTH)-1); 229 225 _printf("\n[GIET DEBUG COPROC] P[%d,%d,%d] executes _mwr_isr() at cycle %d\n" 230 " for t ask%d running on P[%d,%d,%d] / error = %d\n",226 " for thread %d running on P[%d,%d,%d] / error = %d\n", 231 227 x , y , p , _get_proctime() , r_ltid , r_x , r_y , r_p , error ); 232 228 #endif -
soft/giet_vm/giet_drivers/sdc_driver.c
r657 r709 32 32 /////////////////////////////////////////////////////////////////////////////////// 33 33 34 // global index ot the t ask, for each entry in the command list35 __attribute__((section(".kdata"))) 36 unsigned int _ahci_ gtid[32];34 // global index ot the thread, for each entry in the command list 35 __attribute__((section(".kdata"))) 36 unsigned int _ahci_trdid[32]; 37 37 38 38 // status of the command, for each entry in the command list … … 406 406 407 407 ///////////////////////////////////////////////////////////////// 408 // in descheduling mode, we deschedule the t ask409 // and use an interrupt to reschedule the t ask.408 // in descheduling mode, we deschedule the thread 409 // and use an interrupt to reschedule the thread. 410 410 // We need a critical section, because we must set the NORUN bit 411 411 // before to launch the transfer, and we don't want to be … … 422 422 #endif 423 423 unsigned int save_sr; 424 unsigned int ltid = _get_ current_task_id();424 unsigned int ltid = _get_thread_ltid(); 425 425 426 426 // activates interrupt 427 427 _sdc_set_register( AHCI_PXIE , 0x00000001 ); 428 428 429 // set _ahci_ gtid[ptw]430 _ahci_ gtid[ptw] = (procid<<16) + ltid;429 // set _ahci_trdid[ptw] 430 _ahci_trdid[ptw] = (x<<24) + (y<<16) + (p<<8) + ltid; 431 431 432 432 // enters critical section … … 435 435 // Set NORUN_MASK_IOC bit 436 436 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 437 unsigned int* ptr = &psched->context[ltid] [CTX_NORUN_ID];437 unsigned int* ptr = &psched->context[ltid].slot[CTX_NORUN_ID]; 438 438 _atomic_or( ptr , NORUN_MASK_IOC ); 439 439 … … 441 441 _sdc_set_register( AHCI_PXCI, (1<<ptw) ); 442 442 443 // deschedule t ask443 // deschedule thread 444 444 _ctx_switch(); 445 445 446 446 #if GIET_DEBUG_IOC 447 447 if (_get_proctime() > GIET_DEBUG_IOC) 448 _printf("\n[DEBUG SDC] _sdc_access() : t ask%d on P[%d,%d,%d] resume at cycle %d\n",448 _printf("\n[DEBUG SDC] _sdc_access() : thread %d on P[%d,%d,%d] resume at cycle %d\n", 449 449 ltid , x , y , p , _get_proctime() ); 450 450 #endif … … 497 497 _sdc_set_register( AHCI_PXIS , 0 ); 498 498 499 // identify waiting task 500 unsigned int procid = _ahci_gtid[cmd_id]>>16; 501 unsigned int ltid = _ahci_gtid[cmd_id] & 0xFFFF; 502 unsigned int cluster = procid >> P_WIDTH; 503 unsigned int x = cluster >> Y_WIDTH; 504 unsigned int y = cluster & ((1<<Y_WIDTH)-1); 505 unsigned int p = procid & ((1<<P_WIDTH)-1); 506 499 // identify waiting thread 500 unsigned int x = (_ahci_trdid[cmd_id]>>24) & 0xFF; 501 unsigned int y = (_ahci_trdid[cmd_id]>>16) & 0xFF; 502 unsigned int p = (_ahci_trdid[cmd_id]>> 8) & 0xFF; 503 unsigned int ltid = (_ahci_trdid[cmd_id] ) & 0xFF; 504 507 505 // Reset NORUN_MASK_IOC bit 508 506 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 509 _atomic_and( &psched->context[ltid] [CTX_NORUN_ID] , ~NORUN_MASK_IOC );510 511 // send a WAKUP WTI to processor running the waiting t ask512 _xcu_send_wti( cluster ,507 _atomic_and( &psched->context[ltid].slot[CTX_NORUN_ID] , ~NORUN_MASK_IOC ); 508 509 // send a WAKUP WTI to processor running the waiting thread 510 _xcu_send_wti( (x<<Y_WIDTH) + y, 513 511 p , 514 512 0 ); // don't force context switch … … 517 515 if (_get_proctime() > GIET_DEBUG_IOC) 518 516 _printf("\n[DEBUG SDC] _sdc_isr() : command %d completed at cycle %d\n" 519 " resume t ask%d running on P[%d,%d,%d] / status = %x\n",517 " resume thread %d running on P[%d,%d,%d] / status = %x\n", 520 518 cmd_id , _get_proctime() , 521 519 ltid , x , y , p , _ahci_status[cmd_id] ); -
soft/giet_vm/giet_drivers/tty_driver.c
r605 r709 19 19 20 20 //////////////////////////////////////////////////////////////////////////////////// 21 // extern variables 22 //////////////////////////////////////////////////////////////////////////////////// 23 24 // This variable is allocated in kernel_init.c file 25 extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 26 27 //////////////////////////////////////////////////////////////////////////////////// 21 28 // global variables 22 29 //////////////////////////////////////////////////////////////////////////////////// 23 30 31 __attribute__((section(".kdata"))) 32 tty_fifo_t _tty_rx_fifo[NB_TTY_CHANNELS]; 33 34 /* 24 35 __attribute__((section(".kdata"))) 25 36 unsigned int _tty_rx_buf[NB_TTY_CHANNELS]; … … 27 38 __attribute__((section(".kdata"))) 28 39 unsigned int _tty_rx_full[NB_TTY_CHANNELS]; 40 41 __attribute__((section(".kdata"))) 42 unsigned int _tty_rx_trdid[NB_TTY_CHANNELS]; 43 */ 29 44 30 45 //////////////////////////////////////////////////////////////////////////////////// … … 52 67 void _tty_init( unsigned int channel ) 53 68 { 54 _tty_rx_full[channel] = 0; 69 _tty_rx_fifo[channel].sts = 0; 70 _tty_rx_fifo[channel].ptr = 0; 71 _tty_rx_fifo[channel].ptw = 0; 55 72 } 56 73 … … 60 77 unsigned int channel ) // TTY channel 61 78 { 62 // transfer character to kernel buffer and acknowledge TTY IRQ63 _tty_rx_buf[channel] = _tty_get_register( channel, TTY_READ );79 // get pointer on TTY_RX FIFO 80 tty_fifo_t* fifo = &_tty_rx_fifo[channel]; 64 81 65 // flush pending memory writes66 asm volatile( "sync" );82 // get character from TTY_RX channel and acknowledge IRQ 83 unsigned int data = _tty_get_register( channel, TTY_READ ); 67 84 68 // set kernel buffer status 69 _tty_rx_full[channel] = 1; 85 // transfer character to FIFO if not full 86 // discard incoming character if full 87 if ( fifo->sts < TTY_FIFO_DEPTH ) 88 { 89 // store data into FIFO 90 fifo->data[fifo->ptw] = (char)data; 70 91 71 #if GIET_DEBUG_IRQS // we don't take the TTY lock to avoid deadlock 72 unsigned int gpid = _get_procid(); 73 unsigned int cluster_xy = gpid >> P_WIDTH; 74 unsigned int x = cluster_xy >> Y_WIDTH; 75 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 76 unsigned int lpid = gpid & ((1<<P_WIDTH)-1); 77 _puts("\n[IRQS DEBUG] Processor["); 78 _putd(x ); 79 _puts(","); 80 _putd(y ); 81 _puts(","); 82 _putd(lpid ); 83 _puts("] enters _tty_rx_isr() at cycle "); 84 _putd(_get_proctime() ); 85 _puts("\n read byte = "); 86 _putx(_tty_rx_buf[channel] ); 87 _puts("\n"); 88 #endif 92 // avoid race 93 asm volatile( "sync" ); 89 94 95 // update FIFO state 96 fifo->ptw = (fifo->ptw + 1) % TTY_FIFO_DEPTH; 97 fifo->sts = fifo->sts + 1; 98 } 99 100 // get owner thread indexes 101 unsigned int trdid = fifo->trdid; 102 unsigned int x = (trdid >> 24) & 0xFF; 103 unsigned int y = (trdid >> 16) & 0xFF; 104 unsigned int p = (trdid >> 8) & 0xFF; 105 unsigned int ltid = (trdid ) & 0xFF; 106 107 // Reset NORUN_MASK_TTY bit 108 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 109 unsigned int* ptr = &psched->context[ltid].slot[CTX_NORUN_ID]; 110 _atomic_and( ptr , ~NORUN_MASK_TTY ); 90 111 } 91 112 … … 95 116 unsigned int channel ) // TTY channel 96 117 { 97 _p uts("\n[GIET ERROR] the _tty_tx_isr() is not implemented\n");118 _printf("\n[GIET ERROR] the _tty_tx_isr() is not implemented\n"); 98 119 _exit(); 99 120 } -
soft/giet_vm/giet_drivers/tty_driver.h
r496 r709 27 27 #include "kernel_locks.h" 28 28 29 29 30 /////////////////////////////////////////////////////////////////////////////////// 30 31 // registers offsets … … 41 42 }; 42 43 44 45 ////////////////////////////////////////////////////////////////////////////////// 46 // struct tty_fifo_t 47 ////////////////////////////////////////////////////////////////////////////////// 48 49 #define TTY_FIFO_DEPTH 16 50 51 typedef struct tty_fifo_s // 32 bytes 52 { 53 char data[TTY_FIFO_DEPTH]; // one char per slot 54 unsigned int trdid; // owner thread trdid 55 unsigned int ptr; // next free slot index 56 unsigned int ptw; // next full slot index 57 unsigned int sts; // number of full slots 58 } tty_fifo_t; 59 43 60 ////////////////////////////////////////////////////////////////////////////////// 44 61 // access functions -
soft/giet_vm/giet_fat32/fat32.c
r707 r709 38 38 #include <vmem.h> 39 39 #include <kernel_malloc.h> 40 #include <ctx_handler.h> 40 41 #include <bdv_driver.h> 41 42 #include <hba_driver.h> … … 93 94 #if GIET_DEBUG_FAT 94 95 static void _display_fat_descriptor(); 95 #endif96 97 /////////////////////////////////////////////////////////////////////////////////98 // This debug function displays the sequence of clusters allocated to a99 // file (or directory) identified by the "inode" argument.100 /////////////////////////////////////////////////////////////////////////////////101 102 #if GIET_DEBUG_FAT103 static void _display_clusters_list( fat_inode_t* inode );104 96 #endif 105 97 … … 593 585 594 586 595 #if GIET_DEBUG_FAT587 #if 0 596 588 //////////////////////////////////////////////////////// 597 589 static void _display_clusters_list( fat_inode_t* inode ) … … 2832 2824 } 2833 2825 2834 // takes the lock 2826 // takes the FAT lock and register it in thread context 2827 static_scheduler_t* psched = _get_sched(); 2828 unsigned int ltid = _get_thread_ltid(); 2835 2829 _spin_lock_acquire( &_fat.fat_lock ); 2830 _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 2836 2831 2837 2832 // get inode pointer … … 2841 2836 { 2842 2837 _spin_lock_release( &_fat.fat_lock ); 2838 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 2839 2843 2840 _printf("\n[FAT ERROR] _fat_open(): path to parent not found" 2844 2841 " for file <%s>\n", pathname ); … … 2848 2845 { 2849 2846 _spin_lock_release( &_fat.fat_lock ); 2847 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 2848 2850 2849 _printf("\n[FAT ERROR] _fat_open(): one name in path too long" 2851 2850 " for file <%s>\n", pathname ); … … 2855 2854 { 2856 2855 _spin_lock_release( &_fat.fat_lock ); 2856 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 2857 2857 2858 _printf("\n[FAT ERROR] _fat_open(): file not found" 2858 2859 " for file <%s>\n", pathname ); … … 2890 2891 { 2891 2892 _spin_lock_release( &_fat.fat_lock ); 2893 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 2894 2892 2895 _printf("\n[FAT ERROR] _fat_open(): cannot update parent directory" 2893 2896 " for file <%s>\n" , pathname ); … … 2901 2904 { 2902 2905 _spin_lock_release( &_fat.fat_lock ); 2906 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 2907 2903 2908 _printf("\n[FAT ERROR] _fat_open(): cannot update DATA region " 2904 2909 " for parent of file <%s>\n", pathname ); … … 2912 2917 { 2913 2918 _spin_lock_release( &_fat.fat_lock ); 2919 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 2920 2914 2921 _printf("\n[FAT ERROR] _fat_open(): cannot update FAT region" 2915 2922 " for file <%s>\n", pathname ); … … 2921 2928 { 2922 2929 _spin_lock_release( &_fat.fat_lock ); 2930 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 2931 2923 2932 _printf("\n[FAT ERROR] _fat_open(): cannot update FS-INFO" 2924 2933 " for file <%s>\n", pathname ); … … 2952 2961 { 2953 2962 _spin_lock_release( &_fat.fat_lock ); 2963 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 2964 2954 2965 _printf("\n[FAT ERROR] _fat_open(): File-Descriptors-Array full\n"); 2955 2966 return GIET_FAT32_TOO_MANY_OPEN_FILES; … … 2979 2990 { 2980 2991 _spin_lock_release( &_fat.fat_lock ); 2992 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 2993 2981 2994 _printf("\n[FAT ERROR] _fat_open(): can't truncate file\n"); 2982 2995 return GIET_FAT32_IO_ERROR; … … 2987 3000 { 2988 3001 _spin_lock_release( &_fat.fat_lock ); 3002 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3003 2989 3004 _printf("\n[FAT ERROR] _fat_open(): can't truncate file\n"); 2990 3005 return GIET_FAT32_IO_ERROR; … … 2994 3009 // releases the lock 2995 3010 _spin_lock_release( &_fat.fat_lock ); 3011 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3012 2996 3013 2997 3014 #if GIET_DEBUG_FAT … … 3036 3053 } 3037 3054 3038 // takes lock 3055 // takes the FAT lock and register it in thread context 3056 static_scheduler_t* psched = _get_sched(); 3057 unsigned int ltid = _get_thread_ltid(); 3039 3058 _spin_lock_acquire( &_fat.fat_lock ); 3059 _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 3040 3060 3041 3061 if( _fat.fd[fd_id].allocated == 0 ) 3042 3062 { 3043 3063 _spin_lock_release( &_fat.fat_lock ); 3064 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3065 3044 3066 _printf("\n[FAT ERROR] _fat_close(): file not open\n"); 3045 3067 return GIET_FAT32_NOT_OPEN; … … 3067 3089 { 3068 3090 _spin_lock_release( &_fat.fat_lock ); 3091 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3092 3069 3093 _printf("\n[FAT ERROR] _fat_close(): cannot write dirty clusters " 3070 3094 "for file <%s>\n", inode->name ); … … 3084 3108 { 3085 3109 _spin_lock_release( &_fat.fat_lock ); 3110 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3111 3086 3112 _printf("\n[FAT ERROR] _fat_close(): cannot write dirty clusters " 3087 3113 "for directory <%s>\n", inode->parent->name ); … … 3111 3137 // release lock 3112 3138 _spin_lock_release( &_fat.fat_lock ); 3139 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3113 3140 3114 3141 return GIET_FAT32_OK; … … 3161 3188 3162 3189 ///////////////////////////////////////////////////////////////////////////////// 3163 // The following function implements the "giet_fat_read()" system call. 3164 // It transfers "count" bytes from the File_Cache associated to the file 3165 // identified by "fd_id", to the user "buffer", from the current file offset. 3190 // The following function implements the "giet_fat_read()" system call, 3191 // but can also be used by the kernel in physical addressing mode. 3192 // It transfers <count> bytes from the File_Cache associated to the file 3193 // identified by <fd_id>, to the destination buffer defined by <vaddr>. 3194 // It uses the current file offset defined in the file descriptor. 3195 // If the <extend> 16 MSB bits are non zero, it uses physical addressing: 3196 // the physical address is computed as extend[15:0] | vaddr[31:0] 3166 3197 // In case of miss in the File_Cache, it loads all involved clusters into cache. 3167 3198 ///////////////////////////////////////////////////////////////////////////////// … … 3175 3206 ///////////////////////////////////////////////////////////////////////////////// 3176 3207 int _fat_read( unsigned int fd_id, // file descriptor index 3177 paddr_t buffer, // destination buffer3208 unsigned int vaddr, // destination buffer vaddr 3178 3209 unsigned int count, // number of bytes to read 3179 unsigned int phys ) // use physical_memcpy 3180 { 3181 // checking FAT initialized 3182 if( _fat.initialized != FAT_INITIALIZED ) 3183 { 3184 _printf("\n[FAT ERROR] _fat_write(): FAT not initialized\n"); 3185 return GIET_FAT32_NOT_INITIALIZED; 3186 } 3187 3188 // check fd_id overflow 3189 if ( fd_id >= GIET_OPEN_FILES_MAX ) 3190 { 3191 _printf("\n[FAT ERROR] _fat_read(): illegal file descriptor\n"); 3192 return GIET_FAT32_INVALID_FD; 3193 } 3194 3195 // check file is open 3196 if ( _fat.fd[fd_id].allocated == 0 ) 3197 { 3198 _printf("\n[FAT ERROR] _fat_read(): file not open\n"); 3199 return GIET_FAT32_NOT_OPEN; 3200 } 3201 3202 // takes lock 3203 _spin_lock_acquire( &_fat.fat_lock ); 3204 3205 // get file inode pointer and offset 3206 fat_inode_t* inode = _fat.fd[fd_id].inode; 3207 unsigned int seek = _fat.fd[fd_id].seek; 3208 3209 // check count & seek versus file size 3210 if ( count + seek > inode->size && !inode->is_dir ) 3211 { 3212 _spin_lock_release( &_fat.fat_lock ); 3213 _printf("\n[FAT ERROR] _fat_read(): file too small" 3214 " / seek = %x / count = %x / file_size = %x\n", 3215 seek , count , inode->size ); 3216 return 0; 3217 } 3218 3219 // compute first_cluster_id and first_byte_to_move 3220 unsigned int first_cluster_id = seek >> 12; 3221 unsigned int first_byte_to_move = seek & 0xFFF; 3222 3223 // compute last_cluster and last_byte_to_move 3224 unsigned int last_cluster_id = (seek + count - 1) >> 12; 3225 unsigned int last_byte_to_move = (seek + count - 1) & 0xFFF; 3210 unsigned int extend ) // physical address extension 3211 { 3226 3212 3227 3213 #if GIET_DEBUG_FAT … … 3231 3217 unsigned int p = procid & ((1<<P_WIDTH)-1); 3232 3218 if ( _get_proctime() > GIET_DEBUG_FAT ) 3233 _printf("\n[DEBUG FAT] _fat_read(): P[%d,%d,%d] enters for file <%s> " 3234 " / bytes = %x / offset = %x\n" 3235 "first_cluster_id = %x / first_byte_to_move = %x" 3219 _printf("\n[DEBUG FAT] _fat_read(): P[%d,%d,%d] enters at cycle %d\n" 3220 " fd = %d / vaddr = %x / bytes = %x / extend = %x\n", 3221 x , y , p , _get_proctime(), 3222 fd_id , vaddr , count , extend ); 3223 #endif 3224 3225 // checking FAT initialized 3226 if( _fat.initialized != FAT_INITIALIZED ) 3227 { 3228 _printf("\n[FAT ERROR] _fat_read(): FAT not initialized\n"); 3229 return GIET_FAT32_NOT_INITIALIZED; 3230 } 3231 3232 // check fd_id overflow 3233 if ( fd_id >= GIET_OPEN_FILES_MAX ) 3234 { 3235 _printf("\n[FAT ERROR] _fat_read(): illegal file descriptor\n"); 3236 return GIET_FAT32_INVALID_FD; 3237 } 3238 3239 // check file is open 3240 if ( _fat.fd[fd_id].allocated == 0 ) 3241 { 3242 _printf("\n[FAT ERROR] _fat_read(): file not open\n"); 3243 return GIET_FAT32_NOT_OPEN; 3244 } 3245 3246 // takes the FAT lock and register it in thread context 3247 static_scheduler_t* psched = _get_sched(); 3248 unsigned int ltid = _get_thread_ltid(); 3249 _spin_lock_acquire( &_fat.fat_lock ); 3250 _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 3251 3252 3253 // get file inode pointer and offset 3254 fat_inode_t* inode = _fat.fd[fd_id].inode; 3255 unsigned int seek = _fat.fd[fd_id].seek; 3256 3257 // check count & seek versus file size 3258 if ( count + seek > inode->size && !inode->is_dir ) 3259 { 3260 _spin_lock_release( &_fat.fat_lock ); 3261 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3262 3263 _printf("\n[FAT ERROR] _fat_read(): file too small" 3264 " / seek = %x / count = %x / file_size = %x\n", 3265 seek , count , inode->size ); 3266 return 0; 3267 } 3268 3269 // compute first_cluster_id and first_byte_to_move 3270 unsigned int first_cluster_id = seek >> 12; 3271 unsigned int first_byte_to_move = seek & 0xFFF; 3272 3273 // compute last_cluster and last_byte_to_move 3274 unsigned int last_cluster_id = (seek + count - 1) >> 12; 3275 unsigned int last_byte_to_move = (seek + count - 1) & 0xFFF; 3276 3277 #if GIET_DEBUG_FAT 3278 if ( _get_proctime() > GIET_DEBUG_FAT ) 3279 _printf("\n[DEBUG FAT] _fat_read(): P[%d,%d,%d] search file <%s> with seek = %x\n " 3280 " first_cluster_id = %x / first_byte_to_move = %x" 3236 3281 " / last_cluster_id = %x / last_byte_to_move = %x\n", 3237 x , y , p , inode->name , count ,seek ,3282 x , y , p , inode->name , seek , 3238 3283 first_cluster_id , first_byte_to_move , last_cluster_id , last_byte_to_move ); 3239 3284 #endif … … 3252 3297 { 3253 3298 _spin_lock_release( &_fat.fat_lock ); 3299 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3300 3254 3301 _printf("\n[FAT ERROR] _fat_read(): cannot load file <%s>\n", 3255 3302 inode->name ); … … 3289 3336 } 3290 3337 3291 // move data 3292 if ( !phys ) 3293 { 3294 void* dest = (void*)(unsigned int)buffer + done; 3295 3296 memcpy( dest, source, nbytes ); 3297 } 3298 else 3338 // move data 3339 if ( (extend & 0xFFFF0000) == 0 ) // no physical addressing 3340 { 3341 char* dest = (char*)(vaddr + done); 3342 memcpy( dest , source , nbytes ); 3343 } 3344 else // physical addressing required 3299 3345 { 3300 3346 unsigned int flags; 3301 paddr_t pdest = buffer + done;3347 paddr_t pdest = (((paddr_t)(extend & 0x0000FFFF))<<32) + vaddr + done; 3302 3348 paddr_t psource = _v2p_translate( (unsigned int)source, &flags ); 3303 3304 _physical_memcpy( pdest, psource, nbytes ); 3349 _physical_memcpy( pdest , psource , nbytes ); 3305 3350 } 3306 3351 … … 3319 3364 // release lock 3320 3365 _spin_lock_release( &_fat.fat_lock ); 3366 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3321 3367 3322 3368 return done; … … 3327 3373 3328 3374 ///////////////////////////////////////////////////////////////////////////////// 3329 // The following function implements the "giet_fat_write()" system call. 3330 // It transfers "count" bytes to the fat_cache associated to the file 3331 // identified by "fd_id", from the user "buffer", using the current file offset. 3375 // The following function implements the "giet_fat_write()" system call, 3376 // but can also be used by the kernel in physical addressing mode. 3377 // It transfers <count> bytes to the File_Cache associated to the file 3378 // identified by <fd_id>, from the source buffer defined by <vaddr>. 3379 // It uses the current file offset defined in the file descriptor. 3380 // If the <extend> 16 MSB bits are non zero, it uses physical addressing: 3381 // the physical address is computed as extend[15:0] | vaddr[31:0] 3332 3382 // It increases the file size and allocate new clusters if (count + offset) 3333 3383 // is larger than the current file size. Then it loads and updates all … … 3344 3394 ///////////////////////////////////////////////////////////////////////////////// 3345 3395 int _fat_write( unsigned int fd_id, // file descriptor index 3346 void* buffer, // source buffer 3347 unsigned int count ) // number of bytes to write 3396 unsigned int vaddr, // source buffer vaddr 3397 unsigned int count, // number of bytes to write 3398 unsigned int extend ) // physical address extension 3348 3399 { 3349 3400 // checking FAT initialized … … 3354 3405 } 3355 3406 3356 // takes lock 3407 // takes the FAT lock and register it in thread context 3408 static_scheduler_t* psched = _get_sched(); 3409 unsigned int ltid = _get_thread_ltid(); 3357 3410 _spin_lock_acquire( &_fat.fat_lock ); 3411 _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 3412 3358 3413 3359 3414 // check fd_id overflow … … 3361 3416 { 3362 3417 _spin_lock_release( &_fat.fat_lock ); 3418 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3419 3363 3420 _printf("\n[FAT ERROR] _fat_write(): illegal file descriptor\n"); 3364 3421 return GIET_FAT32_INVALID_FD; … … 3369 3426 { 3370 3427 _spin_lock_release( &_fat.fat_lock ); 3428 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3429 3371 3430 _printf("\n[FAT ERROR] _fat_write(): file not open\n" ); 3372 3431 return GIET_FAT32_NOT_OPEN; … … 3377 3436 { 3378 3437 _spin_lock_release( &_fat.fat_lock ); 3438 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3439 3379 3440 _printf("\n[FAT ERROR] _fat_write(): file <%s> is read-only\n", 3380 3441 _fat.fd[fd_id].inode->name ); … … 3429 3490 { 3430 3491 _spin_lock_release( &_fat.fat_lock ); 3492 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3493 3431 3494 _printf("\n[FAT ERROR] _fat_write(): no free clusters" 3432 3495 " for file <%s>\n", _fat.fd[fd_id].inode->name ); … … 3439 3502 { 3440 3503 _spin_lock_release( &_fat.fat_lock ); 3504 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3505 3441 3506 _printf("\n[FAT ERROR] _fat_write(): cannot update parent directory entry" 3442 3507 " for file <%s>\n", _fat.fd[fd_id].inode->name ); … … 3483 3548 { 3484 3549 _spin_lock_release( &_fat.fat_lock ); 3550 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3551 3485 3552 _printf("\n[FAT ERROR] _fat_write(): cannot load file <%s>\n", 3486 3553 inode->name ); … … 3498 3565 3499 3566 // compute memcpy arguments 3500 unsigned char* source = (unsigned char*)buffer + done;3501 3567 unsigned char* dest; 3502 3568 unsigned int nbytes; … … 3522 3588 } 3523 3589 3524 //move date 3525 memcpy( dest , source , nbytes ); 3590 // move data 3591 if ( (extend & 0xFFFF0000) == 0 ) // no physical addressing 3592 { 3593 char* source = (char*)(vaddr + done); 3594 memcpy( dest , source , nbytes ); 3595 } 3596 else // physical addressing required 3597 { 3598 unsigned int flags; 3599 paddr_t psource = (((paddr_t)(extend & 0x0000FFFF))<<32) + vaddr + done; 3600 paddr_t pdest = _v2p_translate( (unsigned int)dest , &flags ); 3601 _physical_memcpy( pdest , psource , nbytes ); 3602 } 3603 3526 3604 done = done + nbytes; 3527 3605 … … 3539 3617 // release lock 3540 3618 _spin_lock_release( &_fat.fat_lock ); 3619 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3541 3620 3542 3621 return done; … … 3577 3656 } 3578 3657 3579 // takes lock 3658 // takes the FAT lock and register it in thread context 3659 static_scheduler_t* psched = _get_sched(); 3660 unsigned int ltid = _get_thread_ltid(); 3580 3661 _spin_lock_acquire( &_fat.fat_lock ); 3662 _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 3663 3581 3664 3582 3665 // check file open … … 3584 3667 { 3585 3668 _spin_lock_release( &_fat.fat_lock ); 3669 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3670 3586 3671 _printf("\n[FAT ERROR] _fat_lseek(): file not open\n"); 3587 3672 return GIET_FAT32_NOT_OPEN; … … 3596 3681 { 3597 3682 _spin_lock_release( &_fat.fat_lock ); 3683 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3684 3598 3685 _printf("\n[FAT ERROR] _fat_lseek(): illegal whence value\n"); 3599 3686 return GIET_FAT32_INVALID_ARG; … … 3615 3702 // release lock 3616 3703 _spin_lock_release( &_fat.fat_lock ); 3704 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3617 3705 3618 3706 return new_seek; … … 3665 3753 } 3666 3754 3667 // take the lock 3755 // takes the FAT lock and register it in thread context 3756 static_scheduler_t* psched = _get_sched(); 3757 unsigned int ltid = _get_thread_ltid(); 3668 3758 _spin_lock_acquire( &_fat.fat_lock ); 3759 _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 3760 3669 3761 3670 3762 // get searched file inode … … 3680 3772 { 3681 3773 _spin_lock_release( &_fat.fat_lock ); 3774 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3775 3682 3776 _printf("\n[FAT ERROR] _fat_remove(): file <%s> not found\n", 3683 3777 pathname ); … … 3687 3781 { 3688 3782 _spin_lock_release( &_fat.fat_lock ); 3783 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3784 3689 3785 _printf("\n[FAT ERROR] _fat_remove(): name too long in <%s>\n", 3690 3786 pathname ); … … 3696 3792 { 3697 3793 _spin_lock_release( &_fat.fat_lock ); 3794 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3795 3698 3796 _printf("\n[FAT ERROR] _fat_remove(): <%s> is a directory\n", 3699 3797 pathname ); … … 3703 3801 { 3704 3802 _spin_lock_release( &_fat.fat_lock ); 3803 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3804 3705 3805 _printf("\n[FAT ERROR] _fat_remove(): <%s> is not a directory\n", 3706 3806 pathname ); … … 3718 3818 { 3719 3819 _spin_lock_release( &_fat.fat_lock ); 3820 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3821 3720 3822 _printf("\n[FAT ERROR] _fat_remove(): file <%s> still referenced\n", 3721 3823 pathname ); … … 3730 3832 { 3731 3833 _spin_lock_release( &_fat.fat_lock ); 3834 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3835 3732 3836 _printf("\n[FAT ERROR] _fat_remove(): cannot scan directory <%s>\n", 3733 3837 pathname ); … … 3737 3841 { 3738 3842 _spin_lock_release( &_fat.fat_lock ); 3843 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3844 3739 3845 _printf("\n[FAT ERROR] _fat_remove(): directory <%s> not empty\n", 3740 3846 pathname ); … … 3753 3859 { 3754 3860 _spin_lock_release( &_fat.fat_lock ); 3861 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3862 3755 3863 _printf("\n[FAT ERROR] _fat_remove(): cannot remove <%s> from FS\n", 3756 3864 pathname ); … … 3760 3868 // release lock and return success 3761 3869 _spin_lock_release( &_fat.fat_lock ); 3870 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3762 3871 3763 3872 #if GIET_DEBUG_FAT … … 3821 3930 } 3822 3931 3823 // take the lock 3932 // takes the FAT lock and register it in thread context 3933 static_scheduler_t* psched = _get_sched(); 3934 unsigned int ltid = _get_thread_ltid(); 3824 3935 _spin_lock_acquire( &_fat.fat_lock ); 3936 _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 3937 3825 3938 3826 3939 // get "old" and "old_parent" inode pointers … … 3828 3941 { 3829 3942 _spin_lock_release( &_fat.fat_lock ); 3943 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3944 3830 3945 _printf("\n[FAT ERROR] _fat_rename(): <%s> not found\n", old_path ); 3831 3946 return GIET_FAT32_FILE_NOT_FOUND; … … 3845 3960 { 3846 3961 _spin_lock_release( &_fat.fat_lock ); 3962 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3963 3847 3964 return GIET_FAT32_OK; 3848 3965 } … … 3859 3976 { 3860 3977 _spin_lock_release( &_fat.fat_lock ); 3978 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3979 3861 3980 _printf("\n[FAT ERROR] _fat_rename(): <%s> not found\n", new_path ); 3862 3981 return GIET_FAT32_FILE_NOT_FOUND; … … 3867 3986 { 3868 3987 _spin_lock_release( &_fat.fat_lock ); 3869 _printf("\n[FAT ERROR] _fat_rename(): can't move %s into its own subdirectory\n", old_path ); 3988 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3989 3990 _printf("\n[FAT ERROR] _fat_rename(): can't move %s into own directory\n", old_path ); 3870 3991 return GIET_FAT32_MOVE_INTO_SUBDIR; 3871 3992 } … … 3894 4015 { 3895 4016 _spin_lock_release( &_fat.fat_lock ); 4017 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4018 3896 4019 _printf("\n[FAT ERROR] _fat_rename(): cannot scan directory <%s>\n", 3897 4020 to_remove->name ); … … 3901 4024 { 3902 4025 _spin_lock_release( &_fat.fat_lock ); 4026 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4027 3903 4028 _printf("\n[FAT ERROR] _fat_rename(): directory <%s> not empty\n", 3904 4029 to_remove->name ); … … 3911 4036 { 3912 4037 _spin_lock_release( &_fat.fat_lock ); 4038 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4039 3913 4040 _printf("\n[FAT ERROR] _fat_rename(): file <%s> still referenced\n", 3914 4041 to_remove->name ); … … 3945 4072 { 3946 4073 _spin_lock_release( &_fat.fat_lock ); 4074 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4075 3947 4076 _printf("\n[FAT ERROR] _fat_rename(): cannot add <%s> into <%s>\n", 3948 4077 new->name , new_parent->name ); … … 3959 4088 { 3960 4089 _spin_lock_release( &_fat.fat_lock ); 4090 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4091 3961 4092 _printf("\n[FAT ERROR] _fat_rename(): cannot update <%s> on device\n", 3962 4093 new_parent->name ); … … 3968 4099 { 3969 4100 _spin_lock_release( &_fat.fat_lock ); 4101 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4102 3970 4103 _printf("\n[FAT ERROR] _fat_rename(): cannot remove <%s> from <%s>\n", 3971 4104 old->name , old_parent->name ); … … 3985 4118 { 3986 4119 _spin_lock_release( &_fat.fat_lock ); 4120 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4121 3987 4122 _printf("\n[FAT ERROR] _fat_rename(): cannot update <%s> on device\n", 3988 4123 old_parent->name ); … … 3996 4131 { 3997 4132 _spin_lock_release( &_fat.fat_lock ); 4133 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4134 3998 4135 _printf("\n[FAT ERROR] _fat_rename(): cannot remove <%s> from FS\n", 3999 4136 to_remove->name ); … … 4004 4141 // release lock 4005 4142 _spin_lock_release( &_fat.fat_lock ); 4143 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4006 4144 4007 4145 return GIET_FAT32_OK; … … 4052 4190 } 4053 4191 4054 // takes the lock 4192 // takes the FAT lock and register it in thread context 4193 static_scheduler_t* psched = _get_sched(); 4194 unsigned int ltid = _get_thread_ltid(); 4055 4195 _spin_lock_acquire( &_fat.fat_lock ); 4056 4196 _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 4197 4057 4198 // get inode 4058 4199 unsigned int code = _get_inode_from_path( pathname , &inode ); … … 4061 4202 { 4062 4203 _spin_lock_release( &_fat.fat_lock ); 4204 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4205 4063 4206 _printf("\n[FAT ERROR] _fat_mkdir(): path to parent not found" 4064 4207 " for directory <%s>\n", pathname ); … … 4068 4211 { 4069 4212 _spin_lock_release( &_fat.fat_lock ); 4213 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4214 4070 4215 _printf("\n[FAT ERROR] _fat_mkdir(): one name in path too long" 4071 4216 " for directory <%s>\n", pathname ); … … 4075 4220 { 4076 4221 _spin_lock_release( &_fat.fat_lock ); 4222 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4223 4077 4224 _printf("\n[FAT ERROR] _fat_mkdir(): directory <%s> already exist\n", 4078 4225 pathname ); … … 4098 4245 { 4099 4246 _spin_lock_release( &_fat.fat_lock ); 4247 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4248 4100 4249 _printf("\n[FAT ERROR] _fat_mkdir(): no free cluster" 4101 4250 " for directory <%s>\n" , pathname ); … … 4127 4276 { 4128 4277 _spin_lock_release( &_fat.fat_lock ); 4278 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4279 4129 4280 _printf("\n[FAT ERROR] _fat_mkdir(): cannot update parent directory" 4130 4281 " for directory <%s>\n" , pathname ); … … 4138 4289 { 4139 4290 _spin_lock_release( &_fat.fat_lock ); 4291 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4292 4140 4293 _printf("\n[FAT ERROR] _fat_mkdir(): cannot update DATA region " 4141 4294 " for parent of directory <%s>\n", pathname ); … … 4149 4302 { 4150 4303 _spin_lock_release( &_fat.fat_lock ); 4304 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4305 4151 4306 _printf("\n[FAT ERROR] _fat_mkdir(): cannot update FAT region" 4152 4307 " for directory <%s>\n", pathname ); … … 4158 4313 { 4159 4314 _spin_lock_release( &_fat.fat_lock ); 4315 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4316 4160 4317 _printf("\n[FAT ERROR] _fat_mkdir(): cannot update FS-INFO" 4161 4318 " for directory <%s>\n", pathname ); … … 4169 4326 { 4170 4327 _spin_lock_release( &_fat.fat_lock ); 4328 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4329 4171 4330 _printf("\n[FAT ERROR] _fat_mkdir(): cannot update DATA region" 4172 4331 " for directory <%s>\n", pathname ); … … 4177 4336 // release lock 4178 4337 _spin_lock_release( &_fat.fat_lock ); 4338 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 4179 4339 4180 4340 return GIET_FAT32_OK; … … 4293 4453 { 4294 4454 // seek back to this entry 4295 _spin_lock_acquire( &_fat.fat_lock ); 4296 _fat.fd[fd_id].seek -= DIR_ENTRY_SIZE; 4297 _spin_lock_release( &_fat.fat_lock ); 4455 _atomic_increment( &_fat.fd[fd_id].seek , -DIR_ENTRY_SIZE ); 4298 4456 4299 4457 return GIET_FAT32_NO_MORE_ENTRIES; -
soft/giet_vm/giet_fat32/fat32.h
r707 r709 226 226 227 227 extern int _fat_read( unsigned int fd_id, // file descriptor 228 paddr_t buffer,// destination buffer228 unsigned int vaddr, // destination buffer 229 229 unsigned int count, // number of bytes 230 unsigned int phys ); // use physical_memcpy230 unsigned int extend ); // physical addressing 231 231 232 232 extern int _fat_write( unsigned int fd_id, // file descriptor 233 void* buffer, // source buffer 234 unsigned int count ); // number of bytes 233 unsigned int vaddr, // source buffer 234 unsigned int count, // number of bytes 235 unsigned int extend ); // physical addressing 235 236 236 237 extern int _fat_lseek( unsigned int fd_id, // file descriptor -
soft/giet_vm/giet_kernel/ctx_handler.c
r707 r709 9 9 #include <sys_handler.h> 10 10 #include <giet_config.h> 11 #include <fat32.h> 11 12 #include <hard_config.h> 12 13 #include <utils.h> 13 14 #include <tty0.h> 14 15 #include <xcu_driver.h> 16 #include <bdv_driver.h> 15 17 16 18 ///////////////////////////////////////////////////////////////////////////////// … … 19 21 20 22 // defined in giet_kernel/switch.s file 21 extern void _t ask_switch(unsigned int *, unsigned int *);23 extern void _thread_switch( thread_context_t* , thread_context_t* ); 22 24 23 25 // allocated in boot.c or kernel_init.c files 24 26 extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 25 27 26 27 /////////////////////////////////////////////// 28 static void _ctx_kill_task( unsigned int ltid ) 28 // allocated in kernel_init.c file 29 extern fat_desc_t _fat; 30 31 ////////////////////////////////////////////////////////////////// 32 // This function is called by the _ctx_switch() function. 33 // It desactivates a thread that received a KILL signal. 34 // We must release all ressources allocated to the thread 35 // before the actual desactivation, that uses NORUN_MASK_THREAD. 36 ////////////////////////////////////////////////////////////////// 37 static void _ctx_kill_thread( unsigned int x, 38 unsigned int y, 39 unsigned int p, 40 unsigned int ltid ) 29 41 { 30 42 // get scheduler address 31 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 32 33 // pretend the task to kill is scheduled (required for sys_handler calls) 34 unsigned int cur_task = psched->current; 43 static_scheduler_t* psched = _schedulers[x][y][p]; 44 45 // pretend the thread to kill is the currently scheduled thread 46 // (required by the _sys_***_release() calls) 47 unsigned int cur_thread = psched->current; 35 48 psched->current = ltid; 36 49 50 // release BDV lock if taken and reset BDV peripheral 51 if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_BDV ) 52 { 53 _bdv_set_register( BLOCK_DEVICE_STATUS , 0 ); 54 _spin_lock_release( &_bdv_lock ); 55 } 56 57 // release FAT lock if taken 58 if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_FAT ) 59 { 60 _spin_lock_release( &_fat.fat_lock ); 61 } 62 37 63 // release private TTY terminal if required 38 if ( psched->context[ltid][CTX_TTY_ID] < NB_TTY_CHANNELS ) 39 { 40 _sys_tty_release(); 41 psched->context[ltid][CTX_TTY_ID] = -1; 42 } 64 if ( psched->context[ltid].slot[CTX_TTY_ID] < NB_TTY_CHANNELS ) 65 _sys_tty_release(); 43 66 44 67 // release private TIM channel if required 45 if ( psched->context[ltid][CTX_TIM_ID] < NB_TIM_CHANNELS ) 68 69 if ( psched->context[ltid].slot[CTX_TIM_ID] < NB_TIM_CHANNELS ) 46 70 { 47 71 _sys_tim_release(); 48 psched->context[ltid][CTX_TIM_ID] = -1; 49 } 50 51 // release private NIC_RX channel if required 52 if ( psched->context[ltid][CTX_NIC_RX_ID] < NB_NIC_CHANNELS ) 72 } 73 74 // release private NIC_RX and CMA_RX channels if required 75 if ( psched->context[ltid].slot[CTX_NIC_RX_ID] < NB_NIC_CHANNELS ) 53 76 { 54 77 _sys_nic_release( 1 ); 55 psched->context[ltid][CTX_NIC_RX_ID] = -1; 56 } 57 58 // release private NIC_TX channel if required 59 if ( psched->context[ltid][CTX_NIC_TX_ID] < NB_NIC_CHANNELS ) 78 } 79 80 // release private NIC_TX and CMA_TX channels if required 81 if ( psched->context[ltid].slot[CTX_NIC_TX_ID] < NB_NIC_CHANNELS ) 60 82 { 61 83 _sys_nic_release( 0 ); 62 psched->context[ltid][CTX_NIC_TX_ID] = -1;63 84 } 64 85 65 86 // release private FBF_CMA channel if required 66 if ( psched->context[ltid] [CTX_CMA_FB_ID] < NB_CMA_CHANNELS )87 if ( psched->context[ltid].slot[CTX_CMA_FB_ID] < NB_CMA_CHANNELS ) 67 88 { 68 89 _sys_fbf_cma_release(); 69 psched->context[ltid][CTX_CMA_FB_ID] = -1; 70 } 71 72 // restore scheduled task 73 psched->current = cur_task; 74 75 // set NORUN_MASK_TASK bit 76 _atomic_or( &psched->context[ltid][CTX_NORUN_ID], NORUN_MASK_TASK ); 77 78 } // end _ctx_kill_task() 79 80 81 ////////////////////////////////// 82 void _ctx_display( unsigned int x, 83 unsigned int y, 84 unsigned int p, 85 unsigned int ltid, 86 char* string ) 87 { 88 static_scheduler_t* psched = _schedulers[x][y][p]; 89 _printf("\n########## task[%d,%d,%d,%d] context\n" 90 " - CTX_EPC = %x\n" 91 " - CTX_PTAB = %x\n" 92 " - CTX_PTPR = %x\n" 93 " - CTX_VSID = %x\n" 94 " - CTX_SR = %x\n" 95 " - CTX_RA = %x\n" 96 " - CTX_SP = %x\n" 97 " - CTX_NORUN = %x\n" 98 " - CTX_SIG = %x\n" 99 "########## %s\n", 100 x , y , p , ltid , 101 psched->context[ltid][CTX_EPC_ID], 102 psched->context[ltid][CTX_PTAB_ID], 103 psched->context[ltid][CTX_PTPR_ID], 104 psched->context[ltid][CTX_VSID_ID], 105 psched->context[ltid][CTX_SR_ID], 106 psched->context[ltid][CTX_RA_ID], 107 psched->context[ltid][CTX_SP_ID], 108 psched->context[ltid][CTX_NORUN_ID], 109 psched->context[ltid][CTX_SIG_ID], 110 string ); 111 } // _ctx_display() 90 } 91 92 // restore scheduled thread index 93 psched->current = cur_thread; 94 95 // set NORUN_MASK_THREAD bit to desactivate the target thread 96 psched->context[ltid].slot[CTX_NORUN_ID] = NORUN_MASK_THREAD; 97 98 } // end _ctx_kill_thread() 112 99 113 100 114 101 ////////////////// 115 102 void _ctx_switch() 116 {117 unsigned int gpid = _get_procid();118 unsigned int cluster_xy = gpid >> P_WIDTH;119 unsigned int lpid = gpid & ((1<<P_WIDTH)-1);120 121 // get scheduler address122 static_scheduler_t* psched = (static_scheduler_t*)_get_sched();123 124 // get number of tasks allocated to scheduler125 unsigned int tasks = psched->tasks;126 127 // get current task index128 unsigned int curr_task_id = psched->current;129 130 // select the next task using a round-robin policy131 unsigned int next_task_id;132 unsigned int tid;133 unsigned int found = 0;134 135 for (tid = curr_task_id + 1; tid < curr_task_id + 1 + tasks; tid++)136 {137 next_task_id = tid % tasks;138 139 // this task needs to be killed140 if ( psched->context[next_task_id][CTX_SIG_ID] & SIG_MASK_KILL )141 {142 // acknowledge signal143 _atomic_and( &psched->context[next_task_id][CTX_SIG_ID], ~SIG_MASK_KILL );144 145 _ctx_kill_task( next_task_id );146 }147 148 // test if the task is runable149 if ( psched->context[next_task_id][CTX_NORUN_ID] == 0 )150 {151 found = 1;152 // TODO: don't break to process all pending signals.153 break;154 }155 }156 157 // launch "idle" task if no runable task158 if (found == 0) next_task_id = IDLE_TASK_INDEX;159 160 #if ( GIET_DEBUG_SWITCH & 0x1 )161 unsigned int x = cluster_xy >> Y_WIDTH;162 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);163 if ( _get_proctime() > GIET_DEBUG_SWITCH )164 _printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n",165 curr_task_id, next_task_id, x, y , lpid, _get_proctime() );166 #endif167 168 if (curr_task_id != next_task_id) // actual task switch required169 {170 unsigned int* curr_ctx_vaddr = &(psched->context[curr_task_id][0]);171 unsigned int* next_ctx_vaddr = &(psched->context[next_task_id][0]);172 173 // reset TICK timer counter.174 _xcu_timer_reset_cpt( cluster_xy, lpid );175 176 // set current task index177 psched->current = next_task_id;178 179 // makes context switch180 _task_switch( curr_ctx_vaddr , next_ctx_vaddr );181 }182 } //end _ctx_switch()183 184 185 /////////////////186 void _idle_task()187 103 { 188 104 unsigned int gpid = _get_procid(); … … 192 108 unsigned int p = gpid & ((1<<P_WIDTH)-1); 193 109 110 unsigned int ltid; // index for loops on threads in scheduler 111 112 // get calling thread scheduler address 113 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 114 115 // get number of threads allocated to scheduler 116 unsigned int threads = psched->threads; 117 118 // get current thread ltid 119 unsigned int curr_thread_id = psched->current; 120 121 // first loop on threads: handle all pending KILL signals 122 for ( ltid = 0 ; ltid < threads ; ltid++ ) 123 { 124 if ( psched->context[ltid].slot[CTX_SIGS_ID] & SIGS_MASK_KILL ) 125 { 126 // acknowledge KILL signal 127 _atomic_and( &psched->context[ltid].slot[CTX_SIGS_ID], ~SIGS_MASK_KILL ); 128 129 // desactivate the killed thread 130 _ctx_kill_thread( x , y , p , ltid ); 131 } 132 } 133 134 // second loop: select next thread using a round-robin policy 135 unsigned int next_thread_id; 136 unsigned int found = 0; 137 for ( ltid = curr_thread_id + 1 ; ltid < (curr_thread_id + 1 + threads) ; ltid++ ) 138 { 139 next_thread_id = ltid % threads; 140 141 // test if the thread is runable 142 if ( psched->context[next_thread_id].slot[CTX_NORUN_ID] == 0 ) 143 { 144 found = 1; 145 break; 146 } 147 } 148 149 // launch idle_thread if no runable thread 150 if ( found == 0 ) next_thread_id = IDLE_THREAD_INDEX; 151 152 if ( curr_thread_id != next_thread_id ) // actual thread switch required 153 { 154 155 #if GIET_DEBUG_SWITCH 156 unsigned int x = cluster_xy >> Y_WIDTH; 157 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 158 if ( (_get_proctime() > GIET_DEBUG_SWITCH) && (x == 0) && (y == 0) && (p == 0) ) 159 _printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n", 160 curr_thread_id, next_thread_id, x, y , p, _get_proctime() ); 161 #endif 162 163 thread_context_t* curr_ctx_vaddr = &(psched->context[curr_thread_id]); 164 thread_context_t* next_ctx_vaddr = &(psched->context[next_thread_id]); 165 166 // reset TICK timer counter. 167 _xcu_timer_reset_cpt( cluster_xy, p ); 168 169 // set current thread index 170 psched->current = next_thread_id; 171 172 // makes context switch 173 _thread_switch( curr_ctx_vaddr , next_ctx_vaddr ); 174 } 175 } //end _ctx_switch() 176 177 178 /////////////////// 179 void _idle_thread() 180 { 181 unsigned int gpid = _get_procid(); 182 unsigned int cluster_xy = gpid >> P_WIDTH; 183 unsigned int x = cluster_xy >> Y_WIDTH; 184 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 185 unsigned int p = gpid & ((1<<P_WIDTH)-1); 186 194 187 while(1) 195 188 { 196 189 // initialize counter 197 unsigned int count = GIET_IDLE_T ASK_PERIOD;190 unsigned int count = GIET_IDLE_THREAD_PERIOD; 198 191 199 192 // decounting loop 200 193 asm volatile( 201 194 "move $3, %0 \n" 202 "_idle_t ask_loop: \n"195 "_idle_thread_loop: \n" 203 196 "addi $3, $3, -1 \n" 204 "bnez $3, _idle_t ask_loop \n"197 "bnez $3, _idle_thread_loop \n" 205 198 "nop \n" 206 199 : -
soft/giet_vm/giet_kernel/ctx_handler.h
r707 r709 6 6 ///////////////////////////////////////////////////////////////////////////////// 7 7 // The ctx_handler.h and ctx_handler.c files are part of the GIET-VM nano-kernel. 8 // This code is used to support context switch when several t asks are executing8 // This code is used to support context switch when several threads are executing 9 9 // in time multiplexing on a single processor. 10 // The t asks are statically allocated to a processor in the boot phase, and10 // The threads are statically allocated to a processor in the boot phase, and 11 11 // there is one private scheduler per processor. Each sheduler occupies 8K bytes, 12 // and contains up to 14 t ask contexts (task_id is from 0 to 13).13 // The t ask context [13] is reserved for the "idle" task that does nothing, and14 // is launched by the scheduler when there is no other runable task.12 // and contains up to 14 thread contexts (thread_id is from 0 to 13). 13 // The thread context [13] is reserved for the "idle" thread that is 14 // launched by the scheduler when there is no other runable thread. 15 15 ///////////////////////////////////////////////////////////////////////////////// 16 // A t askcontext is an array of 64 uint32 words => 256 bytes.17 // It contains copies of processor registers (when the t askis preempted)18 // and some general informations associated to a t ask, such as the private19 // peripheral channels allocated to the t ask, the vspace index, the various20 // t ask index (local / global / application), and the runnable status.16 // A thread context is an array of 64 uint32 words => 256 bytes. 17 // It contains copies of processor registers (when the thread is preempted) 18 // and some general informations associated to a thread, such as the private 19 // peripheral channels allocated to the thread, the vspace index, the two 20 // thread index, and the runnable status. 21 21 ///////////////////////////////////////////////////////////////////////////////// 22 22 // ctx[0] <- *** |ctx[8] <- $8 |ctx[16]<- $16 |ctx[24]<- $24 … … 24 24 // ctx[2] <- $2 |ctx[10]<- $10 |ctx[18]<- $18 |ctx[26]<- LO 25 25 // ctx[3] <- $3 |ctx[11]<- $11 |ctx[19]<- $19 |ctx[27]<- HI 26 // ctx[4] <- $4|ctx[12]<- $12 |ctx[20]<- $20 |ctx[28]<- $2827 // ctx[5] <- $5|ctx[13]<- $13 |ctx[21]<- $21 |ctx[29]<- SP28 // ctx[6] <- $6|ctx[14]<- $14 |ctx[22]<- $22 |ctx[30]<- $3029 // ctx[7] <- $7|ctx[15]<- $15 |ctx[23]<- $23 |ctx[31]<- RA26 // ctx[4] <- A0 |ctx[12]<- $12 |ctx[20]<- $20 |ctx[28]<- $28 27 // ctx[5] <- A1 |ctx[13]<- $13 |ctx[21]<- $21 |ctx[29]<- SP 28 // ctx[6] <- A2 |ctx[14]<- $14 |ctx[22]<- $22 |ctx[30]<- $30 29 // ctx[7] <- A3 |ctx[15]<- $15 |ctx[23]<- $23 |ctx[31]<- RA 30 30 // 31 31 // ctx[32]<- EPC |ctx[40]<- TTY |ctx[48]<- TRDID |ctx[56]<- *** 32 // ctx[33]<- CR |ctx[41]<- CMA_FB |ctx[49]<- GTID |ctx[57]<- ***32 // ctx[33]<- CR |ctx[41]<- CMA_FB |ctx[49]<- LTID |ctx[57]<- *** 33 33 // ctx[34]<- SR |ctx[42]<- CMA_RX |ctx[50]<- NORUN |ctx[58]<- *** 34 34 // ctx[35]<- BVAR |ctx[43]<- CMA_TX |ctx[51]<- COPROC |ctx[59]<- *** 35 35 // ctx[36]<- PTAB |ctx[44]<- NIC_RX |ctx[52]<- ENTRY |ctx[60]<- *** 36 // ctx[37]<- LTID |ctx[45]<- NIC_TX |ctx[53]<- SIG|ctx[61]<- ***37 // ctx[38]<- VSID |ctx[46]<- TIM |ctx[54]<- ***|ctx[62]<- ***38 // ctx[39]<- PTPR |ctx[47]<- HBA |ctx[55]<- ***|ctx[63]<- ***36 // ctx[37]<- *** |ctx[45]<- NIC_TX |ctx[53]<- SIGS |ctx[61]<- *** 37 // ctx[38]<- *** |ctx[46]<- TIM |ctx[54]<- VSID |ctx[62]<- *** 38 // ctx[39]<- PTPR |ctx[47]<- HBA |ctx[55]<- LOCKS |ctx[63]<- *** 39 39 ///////////////////////////////////////////////////////////////////////////////// 40 40 … … 45 45 46 46 ///////////////////////////////////////////////////////////////////////////////// 47 // Definition of the taskcontext slots indexes47 // Definition of some thread context slots indexes 48 48 ///////////////////////////////////////////////////////////////////////////////// 49 50 #define CTX_A0_ID 4 // Argument 0 51 #define CTX_A1_ID 5 // Argument 1 52 #define CTX_A2_ID 6 // Argument 2 53 #define CTX_A3_ID 7 // Argument 3 49 54 50 55 #define CTX_SP_ID 29 // Stack Pointer … … 56 61 #define CTX_BVAR_ID 35 // Bad Virtual Address Register (CP0) 57 62 #define CTX_PTAB_ID 36 // Page Table Virtual address 58 #define CTX_LTID_ID 37 // Local Task Index (in scheduler) 59 #define CTX_VSID_ID 38 // Vspace Index 63 // 37 64 // 38 60 65 #define CTX_PTPR_ID 39 // Page Table Pointer Register (PADDR>>13) 61 66 … … 69 74 #define CTX_HBA_ID 47 // private HBA channel index 70 75 71 #define CTX_TRDID_ID 48 // Thread Task Index in vspace 72 #define CTX_GTID_ID 49 // Global Task Index in all system 73 #define CTX_NORUN_ID 50 // bit-vector : task runable if all zero 74 #define CTX_COPROC_ID 51 // cluster_xy : coprocessor coordinates 75 #define CTX_ENTRY_ID 52 // Virtual address of task entry point 76 #define CTX_SIG_ID 53 // bit-vector : pending signals for task 76 #define CTX_TRDID_ID 48 // Global Thread Index ( x | y | p | ltid ) 77 #define CTX_LTID_ID 49 // Local Thread Index in scheduler 78 #define CTX_NORUN_ID 50 // bit-vector : thread runable if all zero 79 #define CTX_COPROC_ID 51 // coprocessor coordinates (cluster_xy) 80 #define CTX_ENTRY_ID 52 // Virtual address of thread entry point 81 #define CTX_SIGS_ID 53 // bit-vector : pending signals 82 #define CTX_VSID_ID 54 // Vspace Index 83 #define CTX_LOCKS_ID 55 // bit-vector : kernel locks taken 77 84 78 85 ///////////////////////////////////////////////////////////////////////////////// … … 80 87 ///////////////////////////////////////////////////////////////////////////////// 81 88 82 #define NORUN_MASK_T ASK0x00000001 // Task not active89 #define NORUN_MASK_THREAD 0x00000001 // Task not active 83 90 #define NORUN_MASK_IOC 0x00000002 // Task blocked on IOC transfer 84 91 #define NORUN_MASK_COPROC 0x00000004 // Task blocked on COPROC transfer 92 #define NORUN_MASK_TTY 0x00000008 // Task blocked on TTY_RX transfer 85 93 86 94 ///////////////////////////////////////////////////////////////////////////////// 87 // Definition of the SIG bit-vector masks95 // Definition of the SIGS bit-vector masks 88 96 ///////////////////////////////////////////////////////////////////////////////// 89 97 90 #define SIG _MASK_KILL 0x00000001 // Task will be killed at next tick98 #define SIGS_MASK_KILL 0x00000001 // Task desactivated at next tick 91 99 92 100 ///////////////////////////////////////////////////////////////////////////////// 93 // Definition of the scheduler structure101 // Definition of the LOCKS bit-vector masks 94 102 ///////////////////////////////////////////////////////////////////////////////// 95 103 96 typedef struct static_scheduler_s 104 #define LOCKS_MASK_BDV 0x00000001 // BDV kernel lock taken 105 #define LOCKS_MASK_FAT 0x00000002 // FAT kernel lock taken 106 107 ///////////////////////////////////////////////////////////////////////////////// 108 // Task context and scheduler structures 109 ///////////////////////////////////////////////////////////////////////////////// 110 111 typedef struct thread_context_s // 256 bytes 97 112 { 98 unsigned int context[14][64]; // at most 14 task (including idle_task) 99 unsigned int tasks; // actual number of tasks 100 unsigned int current; // current task index 101 unsigned int hwi_vector[32]; // hardware interrupt vector 102 unsigned int pti_vector[32]; // timer interrupt vector 103 unsigned int wti_vector[32]; // software interrupt vector 104 unsigned int reserved[30]; // padding to 4 Kbytes 105 unsigned int idle_stack[1024]; // private stack for idle stack (4Kbytes) 113 unsigned int slot[64]; 114 } thread_context_t; 115 116 117 typedef struct static_scheduler_s // 8 Kbytes 118 { 119 thread_context_t context[14]; // at most 14 threads (including idle_thread) 120 unsigned int threads; // actual number of allocated threads 121 unsigned int current; // current thread index 122 unsigned int hwi_vector[32]; // hardware interrupt vector 123 unsigned int pti_vector[32]; // timer interrupt vector 124 unsigned int wti_vector[32]; // software interrupt vector 125 unsigned int reserved[30]; // padding to 4 Kbytes 126 unsigned int idle_stack[1024]; // private stack for idle stack (4Kbytes) 106 127 } static_scheduler_t; 107 128 108 #define IDLE_T ASK_INDEX 13129 #define IDLE_THREAD_INDEX 13 109 130 110 131 … … 114 135 115 136 ///////////////////////////////////////////////////////////////////////////////// 116 // This function performs a context switch between the running t ask117 // and another t ask, using a round-robin sheduling policy between all118 // t asks allocated to a given processor (static allocation).119 // It selects the next runable t askto resume execution.120 // If the only runable t ask is the current task, return without context switch.121 // If there is no runable t ask, the scheduler switch to the default "idle" task.122 // The return address contained in $31 is saved in the current t askcontext137 // This function performs a context switch between the running thread 138 // and another thread, using a round-robin sheduling policy between all 139 // threads allocated to a given processor (static allocation). 140 // It selects the next runable thread to resume execution. 141 // If the only runable thread is the current thread, return without context switch. 142 // If there is no runable thread, the scheduler switch to the default "idle" thread. 143 // The return address contained in $31 is saved in the current thread context 123 144 // (in the ctx[31] slot), and the function actually returns to the address 124 // contained in the ctx[31] slot of the next t askcontext.145 // contained in the ctx[31] slot of the next thread context. 125 146 ///////////////////////////////////////////////////////////////////////////////// 126 147 extern void _ctx_switch(); … … 128 149 ///////////////////////////////////////////////////////////////////////////////// 129 150 // The address of this function is used to initialise the return address 130 // in the "idle" t askcontext.151 // in the "idle" thread context. 131 152 ///////////////////////////////////////////////////////////////////////////////// 132 153 extern void _ctx_eret(); 133 154 134 155 ///////////////////////////////////////////////////////////////////////////////// 135 // This function is executed t ask when no other taskcan be executed.156 // This function is executed thread when no other thread can be executed. 136 157 ///////////////////////////////////////////////////////////////////////////////// 137 extern void _idle_task(); 138 139 ///////////////////////////////////////////////////////////////////////////////// 140 // This function displays the context of a task identified by the processor 141 // coordinates (x,y,p), and by the local task index ltid. 142 // The string argument can be used for debug. 143 ///////////////////////////////////////////////////////////////////////////////// 144 extern void _ctx_display( unsigned int x, 145 unsigned int y, 146 unsigned int p, 147 unsigned int ltid, 148 char* string ); 158 extern void _idle_thread(); 149 159 150 160 #endif -
soft/giet_vm/giet_kernel/exc_handler.c
r629 r709 61 61 unsigned int x = cluster_xy >> Y_WIDTH; 62 62 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 63 unsigned int lpid = gpid & ((1<<P_WIDTH)-1); 63 unsigned int p = gpid & ((1<<P_WIDTH)-1); 64 unsigned int trdid = _get_thread_trdid(); 65 unsigned int ltid = _get_thread_ltid(); 64 66 65 unsigned int task = _get_context_slot(CTX_LTID_ID); 66 67 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 67 68 68 69 const char * mips32_exc_str[] = { "strange unknown cause ", … … 74 75 "reserved instruction ", 75 76 "illegal coproc access ", 76 "arithmetic overflow " };77 "arithmetic overflow " }; 77 78 78 _printf("\n[GIET] Exception for t ask %don processor[%d,%d,%d] at cycle %d\n"79 _printf("\n[GIET] Exception for thread %x on processor[%d,%d,%d] at cycle %d\n" 79 80 " - type : %s\n" 80 81 " - EPC : %x\n" 81 82 " - BVAR : %x\n" 82 "...T askdesactivated\n",83 t ask, x, y, lpid, _get_proctime(),83 "...Thread desactivated\n", 84 trdid , x , y , p , _get_proctime(), 84 85 mips32_exc_str[type], _get_epc(), _get_bvar() ); 85 86 86 // goes to sleeping state87 _ set_context_slot( CTX_NORUN_ID , 1);87 // register KILL signal 88 _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL ); 88 89 89 // deschedule 90 // deschedule calling thread 90 91 unsigned int save_sr; 91 92 _it_disable( &save_sr ); -
soft/giet_vm/giet_kernel/irq_handler.c
r702 r709 26 26 #include <tty0.h> 27 27 28 //////////////////////////////////////////////////////////////////////////// 29 // Extern variables 30 //////////////////////////////////////////////////////////////////////////// 31 32 // allocated in sys_handler.c file 33 extern unsigned int _tty_channel_wti[NB_TTY_CHANNELS]; 34 extern unsigned int _tim_channel_wti[NB_TIM_CHANNELS]; 35 extern unsigned int _cma_channel_wti[NB_CMA_CHANNELS]; 36 extern unsigned int _nic_rx_channel_wti[NB_NIC_CHANNELS]; 37 extern unsigned int _nic_tx_channel_wti[NB_NIC_CHANNELS]; 38 28 39 ///////////////////////////////////////////////////////////////////////// 29 40 // Global variables … … 41 52 __attribute__((section(".kdata"))) 42 53 unsigned char _wti_alloc_ter[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 54 55 #define MAX_RETRY 10000 43 56 44 57 ///////////////////////////////////////////////////////////////////////// … … 134 147 } // end _ext_irq_init() 135 148 136 //////////////////////////////////////////// 149 ///////////////////////////////////////////// 137 150 void _ext_irq_alloc( unsigned int isr_type, 138 151 unsigned int isr_channel, … … 143 156 unsigned int wti_addr; // WTI mailbox physical address (32 lsb bits) 144 157 145 // check arguments 158 unsigned int count = MAX_RETRY; 159 160 // check input arguments 146 161 if ( isr_type >= GIET_ISR_TYPE_MAX ) 147 162 { … … 163 178 164 179 // allocate a WTI mailbox to proc[x,y,p] (blocking until success) 180 165 181 while ( 1 ) 166 182 { 183 if ( count == 0 ) 184 { 185 unsigned int trdid = _get_context_slot( CTX_TRDID_ID ); 186 unsigned int vsid = _get_context_slot( CTX_VSID_ID ); 187 _printf("\n[GIET WARNING] thread %x in vspace %d " 188 "running on P[%d,%d,%d] still waiting in _ext_irq_alloc()\n", 189 trdid, vsid, x, y, p ); 190 count = MAX_RETRY; 191 } 192 167 193 if ( _wti_alloc_one[x][y][p] == 0 ) 168 194 { … … 183 209 break; 184 210 } 211 count--; 185 212 } 213 186 214 *wti_index = wti_id; 187 215 … … 196 224 197 225 #if GIET_DEBUG_IRQS 226 if ( _get_proctime() > GIET_DEBUG_IRQS ) 198 227 _printf("\n[DEBUG IRQS] _ext_irq_alloc() for P[%d,%d,%d] at cycle %d\n" 199 228 " wti_id = %d / isr_type = %s / channel = %d / pic_input = %d\n", … … 204 233 } // end ext_irq_alloc() 205 234 206 //////////////////////////////////////////// 235 //////////////////////////////////////////////// 207 236 void _ext_irq_release( unsigned int isr_type, 208 unsigned int isr_channel ) 209 { 210 unsigned int wti_id; // allocated WTI mailbox index in XCU 211 unsigned int irq_id; // external IRQ index in PIC (input) 212 213 // get processor coordinates [x,y,p] 214 unsigned int gpid = _get_procid(); 215 unsigned int cluster_xy = gpid >> P_WIDTH; 216 unsigned int x = cluster_xy >> Y_WIDTH; 217 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 218 unsigned int p = gpid & ((1<<P_WIDTH)-1); 219 220 // check arguments 237 unsigned int channel ) 238 { 239 // check input arguments 221 240 if ( isr_type >= GIET_ISR_TYPE_MAX ) 222 241 { 223 _printf("\n[GIET ERROR] in _ext_irq_release() illegal ISR type\n"); 224 _exit(); 225 } 226 if ( isr_channel >= GIET_ISR_CHANNEL_MAX ) 227 { 228 _printf("\n[GIET ERROR] in _ext_irq_release() : illegal ISR channel\n"); 229 _exit(); 230 } 231 232 // find WTI index 233 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 234 for ( wti_id = 0 ; wti_id < 32 ; wti_id++ ) 235 { 236 if ( psched->wti_vector[wti_id] == (isr_channel<<16 | isr_type) ) 237 break; 238 } 239 if ( wti_id == 32 ) 240 { 241 _printf("\n[GIET ERROR] in _ext_irq_release() : isr not found\n"); 242 return; 243 } 244 242 _printf("\n[GIET ERROR] in _ext_irq_release() : " 243 "illegal ISR type %d\n", isr_type ); 244 _exit(); 245 } 246 if ( channel >= GIET_ISR_CHANNEL_MAX ) 247 { 248 _printf("\n[GIET ERROR] in _ext_irq_release() : " 249 "illegal ISR channel %d\n", channel ); 250 _exit(); 251 } 252 253 // analyse ISR type to get WTI index (wti), and coordinates 254 // of processor (x,y,p) that has been allocated the external IRQ 255 unsigned int wti = 0; 256 unsigned int x = 0; 257 unsigned int y = 0; 258 unsigned int p = 0; 259 260 if ( (isr_type == ISR_TTY_RX) || (isr_type == ISR_TTY_TX) ) 261 { 262 x = (_tty_channel_wti[channel]>>24) & 0xFF; 263 y = (_tty_channel_wti[channel]>>16) & 0xFF; 264 p = (_tty_channel_wti[channel]>> 8) & 0xFF; 265 wti = (_tty_channel_wti[channel] ) & 0xFF; 266 } 267 #if NB_TIM_CHANNELS 268 else if ( isr_type == ISR_TIMER ) 269 { 270 x = (_tim_channel_wti[channel]>>24) & 0xFF; 271 y = (_tim_channel_wti[channel]>>16) & 0xFF; 272 p = (_tim_channel_wti[channel]>> 8) & 0xFF; 273 wti = (_tim_channel_wti[channel] ) & 0xFF; 274 } 275 #endif 276 #if NB_CMA_CHANNELS 277 else if ( isr_type == ISR_CMA ) 278 { 279 x = (_cma_channel_wti[channel]>>24) & 0xFF; 280 y = (_cma_channel_wti[channel]>>16) & 0xFF; 281 p = (_cma_channel_wti[channel]>> 8) & 0xFF; 282 wti = (_cma_channel_wti[channel] ) & 0xFF; 283 } 284 #endif 285 #if NB_NIC_CHANNELS 286 else if ( isr_type == ISR_NIC_RX ) 287 { 288 x = (_nic_rx_channel_wti[channel]>>24) & 0xFF; 289 y = (_nic_rx_channel_wti[channel]>>16) & 0xFF; 290 p = (_nic_rx_channel_wti[channel]>> 8) & 0xFF; 291 wti = (_nic_rx_channel_wti[channel] ) & 0xFF; 292 } 293 else if ( isr_type == ISR_NIC_TX ) 294 { 295 x = (_nic_tx_channel_wti[channel]>>24) & 0xFF; 296 y = (_nic_tx_channel_wti[channel]>>16) & 0xFF; 297 p = (_nic_tx_channel_wti[channel]>> 8) & 0xFF; 298 wti = (_nic_tx_channel_wti[channel] ) & 0xFF; 299 } 300 #endif 301 else 302 { 303 _printf("\n[GIET ERROR] in _ext_irq_release() : " 304 "ISR type %s not supported / thread = %x\n", 305 _isr_type_str[isr_type] , _get_thread_trdid() ); 306 _exit(); 307 } 308 245 309 // desactivates dynamically allocated PIC entry 246 irq_id = _ext_irq_index[isr_type][isr_channel];310 unsigned int irq_id = _ext_irq_index[isr_type][channel]; 247 311 _pic_set_register( irq_id , IOPIC_MASK , 0 ); 248 312 249 313 // releases dynamically allocated WTI mailbox 250 if ( wti _id== p + NB_PROCS_MAX ) _wti_alloc_one[x][y][p] = 0;251 else if ( wti _id== p + 2*NB_PROCS_MAX ) _wti_alloc_two[x][y][p] = 0;252 else if ( wti _id== p + 3*NB_PROCS_MAX ) _wti_alloc_ter[x][y][p] = 0;314 if ( wti == p + NB_PROCS_MAX ) _wti_alloc_one[x][y][p] = 0; 315 else if ( wti == p + 2*NB_PROCS_MAX ) _wti_alloc_two[x][y][p] = 0; 316 else if ( wti == p + 3*NB_PROCS_MAX ) _wti_alloc_ter[x][y][p] = 0; 253 317 else 254 318 { 255 _printf("\n[GIET ERROR] in _ext_irq_release() : illegal WTI index\n"); 319 _printf("\n[GIET ERROR] in _ext_irq_release() : " 320 "WTI = %d / X = %d / Y = %d / P = %d\n", wti , x, y , p ); 256 321 _exit(); 257 322 } … … 294 359 295 360 #if GIET_DEBUG_IRQS // we don't take the TTY lock to avoid deadlocks 361 if ( _get_proctime() > GIET_DEBUG_IRQS ) 296 362 _nolock_printf("\n[DEBUG IRQS] _irq_demux() Processor[%d,%d,%d] enters at cycle %d\n" 297 363 " irq_type = %s / irq_id = %d / isr_type = %s / channel = %d\n", … … 360 426 361 427 unsigned int value; // WTI mailbox value 362 unsigned int save_sr; // save SR value in pre-empted t askstack363 364 unsigned int ltid = _get_ current_task_id();428 unsigned int save_sr; // save SR value in pre-empted thread stack 429 430 unsigned int ltid = _get_thread_ltid(); 365 431 366 432 if ( irq_type != IRQ_TYPE_WTI ) … … 375 441 _xcu_get_wti_value( cluster_xy, irq_id, &value ); 376 442 377 #if GIET_DEBUG_SWITCH 378 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] enters _isr_wakup() at cycle %d\n" 443 #if GIET_DEBUG_IRQS 444 if ( _get_proctime() > GIET_DEBUG_IRQS ) 445 _printf("\n[DEBUG IRQS] P[%d,%d,%d] enters _isr_wakup() at cycle %d\n" 379 446 " WTI index = %d / current ltid = %d / mailbox value = %x\n", 380 447 x , y , p , _get_proctime() , irq_id , ltid , value ); … … 382 449 383 450 // enter critical section and swich context (if required) 384 if ( (ltid == IDLE_T ASK_INDEX) || (value != 0) )451 if ( (ltid == IDLE_THREAD_INDEX) || (value != 0) ) 385 452 { 386 453 _it_disable( &save_sr ); … … 402 469 unsigned int p = gpid & ((1<<P_WIDTH)-1); 403 470 404 unsigned int save_sr; // save SR value in pre-empted t askstack471 unsigned int save_sr; // save SR value in pre-empted thread stack 405 472 406 473 if ( irq_type != IRQ_TYPE_PTI ) … … 415 482 _xcu_timer_reset_irq( cluster_xy, irq_id ); 416 483 417 #if (GIET_DEBUG_SWITCH & 0x1)418 unsigned int ltid = _get_ current_task_id();419 if ( _get_proctime() > GIET_DEBUG_ SWITCH)420 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] enters _isr_tick() at cycle %d\n"484 #if GIET_DEBUG_IRQS 485 unsigned int ltid = _get_thread_ltid(); 486 if ( _get_proctime() > GIET_DEBUG_IRQS ) 487 _printf("\n[DEBUG IRQS] P[%d,%d,%d] enters _isr_tick() at cycle %d\n" 421 488 " WTI index = %d / current ltid = %d\n", 422 489 x , y , p , _get_proctime() , irq_id , ltid ); -
soft/giet_vm/giet_kernel/kernel_init.c
r688 r709 23 23 #include <bdv_driver.h> 24 24 #include <mmc_driver.h> 25 #include <tty_driver.h> 25 26 #include <ctx_handler.h> 26 27 #include <irq_handler.h> 28 #include <sys_handler.h> 27 29 #include <mapping_info.h> 28 30 #include <mips32_registers.h> … … 60 62 #endif 61 63 62 #if !defined(IDLE_T ASK_INDEX)63 # error: You must define IDLE_T ASK_INDEX in the ctx_handler.h file64 #if !defined(IDLE_THREAD_INDEX) 65 # error: You must define IDLE_THREAD_INDEX in the ctx_handler.h file 64 66 #endif 65 67 … … 109 111 volatile unsigned int _kernel_init_done = 0; 110 112 111 // Kernel uses sqt_lock to protect TTY0113 // Kernel uses a sqt_lock to protect TTY0 112 114 __attribute__((section(".kdata"))) 113 115 unsigned int _tty0_boot_mode = 0; 114 116 115 // Kernel uses sqt_lock to protect command allocator in HBA117 // Kernel uses a sqt_lock to protect command allocator in HBA 116 118 __attribute__((section(".kdata"))) 117 119 unsigned int _hba_boot_mode = 0; … … 125 127 //////////////////////////////////////////////////////////////////////////////// 126 128 127 // this variable is defined in tty0.c file129 // this variable is allocated in tty0.c file 128 130 extern sqt_lock_t _tty0_sqt_lock; 129 131 130 // this variable is allocated in mmc_ kernel.c132 // this variable is allocated in mmc_driver.c file 131 133 extern unsigned int _mmc_boot_mode; 132 134 133 //////////////////////////////////////////////////////////////////////////////// 134 // This kernel_init() function completes the kernel initialisation in 6 steps: 135 // this variable is allocated in sys_handler.c file 136 extern unsigned int _tty_channel_alloc[NB_TTY_CHANNELS]; 137 138 //////////////////////////////////////////////////////////////////////////////// 139 // This kernel_init() function completes the kernel initialisation in 5 steps: 135 140 // Step 0 is done by processor[0,0,0]. Steps 1 to 4 are executed in parallel 136 141 // by all processors. … … 138 143 // - step 1 : Each processor initialises scheduler pointers array. 139 144 // - step 2 : Each processor initialises PTAB pointers arrays. 140 // - step 3 : Each processor initialise idle t askand starts TICK timer.145 // - step 3 : Each processor initialise idle thread and starts TICK timer. 141 146 // - step 4 : Each processor set sp, sr, ptpr, epc registers values. 142 147 //////////////////////////////////////////////////////////////////////////////// … … 165 170 _nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes kernel heap init\n", x, y, p ); 166 171 #endif 167 ////// distributed lock for MMC172 ////// distributed locks for MMC 168 173 _mmc_boot_mode = 0; 169 174 _mmc_init_locks(); 170 175 171 176 #if GIET_DEBUG_INIT 172 _nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes MMC distributed lock init\n", x , y , p );177 _nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes MMC distributed locks init\n", x , y , p ); 173 178 #endif 174 179 ////// distributed lock for TTY0 175 180 _sqt_lock_init( &_tty0_sqt_lock ); 181 _tty_channel_alloc[0] = 1; 176 182 177 183 #if GIET_DEBUG_INIT … … 183 189 #if GIET_DEBUG_INIT 184 190 _nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes barrier init\n", x , y , p ); 191 #endif 192 193 ////// TTY fifos initialisation 194 unsigned int tty_id; 195 for ( tty_id = 0 ; tty_id < NB_TTY_CHANNELS ; tty_id++) _tty_init( tty_id ); 196 197 #if GIET_DEBUG_INIT 198 _nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes TTY fifos init\n", x , y , p ); 185 199 #endif 186 200 … … 245 259 246 260 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 247 unsigned int t asks = psched->tasks;261 unsigned int threads = psched->threads; 248 262 249 263 _schedulers[x][y][p] = psched; … … 252 266 _printf("\n[DEBUG KINIT] P[%d,%d,%d] initialises SCHED array\n" 253 267 " - scheduler vbase = %x\n" 254 " - t asks= %d\n",255 x, y, p, (unsigned int)psched, t asks );268 " - threads = %d\n", 269 x, y, p, (unsigned int)psched, threads ); 256 270 #endif 257 271 … … 261 275 262 276 //////////////////////////////////////////////////////////////////////////// 263 // step 2 : each processor that is allocated at least one t askloops264 // on its allocated t asks:265 // - contributes to _ptabs_vaddr [][][] & _ptabs_ptprs[][][]266 // initialisation, from values stored in the t asks contexts.277 // step 2 : each processor that is allocated at least one thread loops 278 // on its allocated threads: 279 // - contributes to _ptabs_vaddr & _ptabs_ptprs arrays 280 // initialisation, from values stored in the threads contexts. 267 281 // - set CTX_RA slot with the kernel _ctx_eret() virtual address. 268 // - set CTX_ENTRY slot that must contain the task entry point,269 // and contain only at this point the virtual address of the270 // memory word containing this entry point.282 // - set CTX_ENTRY & CTX_EPC slots that must contain the thread 283 // entry point. The CTX_ENTRY slot contain only at this point 284 // a pointer on the memory word containing this entry point. 271 285 //////////////////////////////////////////////////////////////////////////// 272 286 273 287 unsigned int ltid; 274 288 275 for (ltid = 0; ltid < t asks; ltid++)289 for (ltid = 0; ltid < threads; ltid++) 276 290 { 277 unsigned int vsid = _get_t ask_slot( x, y, p, ltid , CTX_VSID_ID );278 unsigned int ptab = _get_t ask_slot( x, y, p, ltid , CTX_PTAB_ID );279 unsigned int ptpr = _get_t ask_slot( x, y, p, ltid , CTX_PTPR_ID );291 unsigned int vsid = _get_thread_slot( x, y, p, ltid , CTX_VSID_ID ); 292 unsigned int ptab = _get_thread_slot( x, y, p, ltid , CTX_PTAB_ID ); 293 unsigned int ptpr = _get_thread_slot( x, y, p, ltid , CTX_PTPR_ID ); 280 294 281 295 // initialize PTABS arrays … … 289 303 // set CTX_RA slot 290 304 unsigned int ctx_ra = (unsigned int)(&_ctx_eret); 291 _set_t ask_slot( x, y, p, ltid, CTX_RA_ID, ctx_ra );292 293 // set CTX_ENTRY slot294 unsigned int* ptr = (unsigned int*)_get_t ask_slot(x , y , p , ltid , CTX_ENTRY_ID);305 _set_thread_slot( x, y, p, ltid, CTX_RA_ID, ctx_ra ); 306 307 // set CTX_ENTRY and CTX_EPC slots 308 unsigned int* ptr = (unsigned int*)_get_thread_slot(x , y , p , ltid , CTX_ENTRY_ID); 295 309 unsigned int ctx_entry = *ptr; 296 _set_task_slot( x , y , p , ltid , CTX_ENTRY_ID , ctx_entry ); 310 _set_thread_slot( x , y , p , ltid , CTX_ENTRY_ID , ctx_entry ); 311 _set_thread_slot( x , y , p , ltid , CTX_EPC_ID , ctx_entry ); 297 312 298 313 #if GIET_DEBUG_INIT 299 314 _printf("\n[DEBUG KINIT] P[%d,%d,%d] initialises PTABS arrays" 300 " and context for t ask%d \n"315 " and context for thread %d \n" 301 316 " - ptabs_vaddr[%d][%d][%d] = %x\n" 302 317 " - ptabs_paddr[%d][%d][%d] = %l\n" … … 309 324 #endif 310 325 311 } // end for t asks326 } // end for threads 312 327 313 328 ///////////////////////////////////////// … … 316 331 317 332 //////////////////////////////////////////////////////////////////////////// 318 // step 3 : - Each processor complete idle t askcontext initialisation.333 // step 3 : - Each processor complete idle thread context initialisation. 319 334 // Only CTX_SP, CTX_RA, CTX_EPC, CTX_ENTRY slots, because other 320 335 // slots have been initialised in boot code) 321 336 // The 4 Kbytes idle stack is implemented in the scheduler itself. 322 // - Each processor starts TICK timer, if at least one t ask.337 // - Each processor starts TICK timer, if at least one thread. 323 338 // - P[0,0,0] initialises FAT (not done before, because it must 324 339 // be done after the _ptabs_vaddr[v][x][y] array initialisation, … … 328 343 unsigned int sp = ((unsigned int)psched) + 0x2000; 329 344 unsigned int ra = (unsigned int)(&_ctx_eret); 330 unsigned int entry = (unsigned int)(&_idle_t ask);331 332 _set_t ask_slot( x , y , p , IDLE_TASK_INDEX , CTX_SP_ID , sp );333 _set_t ask_slot( x , y , p , IDLE_TASK_INDEX , CTX_RA_ID , ra );334 _set_t ask_slot( x , y , p , IDLE_TASK_INDEX , CTX_EPC_ID , entry );335 _set_t ask_slot( x , y , p , IDLE_TASK_INDEX , CTX_ENTRY_ID , entry );336 337 if (t asks > 0) _xcu_timer_start( cluster_xy, p, GIET_TICK_VALUE );338 339 #if GIET_DEBUG_INIT 340 _printf("\n[DEBUG KINIT] P[%d,%d,%d] initializes idle_t askand starts TICK\n",345 unsigned int entry = (unsigned int)(&_idle_thread); 346 347 _set_thread_slot( x , y , p , IDLE_THREAD_INDEX , CTX_SP_ID , sp ); 348 _set_thread_slot( x , y , p , IDLE_THREAD_INDEX , CTX_RA_ID , ra ); 349 _set_thread_slot( x , y , p , IDLE_THREAD_INDEX , CTX_EPC_ID , entry ); 350 _set_thread_slot( x , y , p , IDLE_THREAD_INDEX , CTX_ENTRY_ID , entry ); 351 352 if (threads > 0) _xcu_timer_start( cluster_xy, p, GIET_TICK_VALUE ); 353 354 #if GIET_DEBUG_INIT 355 _printf("\n[DEBUG KINIT] P[%d,%d,%d] initializes idle_thread and starts TICK\n", 341 356 x, y, p ); 342 357 #endif … … 358 373 359 374 //////////////////////////////////////////////////////////////////////////// 360 // step 4 : Each processor computes the t askindex (ltid), and the values375 // step 4 : Each processor computes the thread index (ltid), and the values 361 376 // to initialize the SP, SR, PTPR, EPC registers. 362 // It jumps to a runable t ask if possible, and jumps to IDLE-TASK363 // if no task allocated or no runable task.364 //////////////////////////////////////////////////////////////////////////// 365 366 if (t asks == 0) _printf("\n[GIET WARNING] No taskallocated to P[%d,%d,%d]\n",377 // It jumps to a runable thread if possible, 378 // or jumps to IDLE-THREAD if no runable thread. 379 //////////////////////////////////////////////////////////////////////////// 380 381 if (threads == 0) _printf("\n[GIET WARNING] No thread allocated to P[%d,%d,%d]\n", 367 382 x, y, p ); 368 383 369 384 // default value for ltid 370 ltid = IDLE_T ASK_INDEX;371 372 // scan allocated t asks to find a runable task373 unsigned int t ask_id;374 for ( t ask_id = 0 ; task_id < tasks ; task_id++ )385 ltid = IDLE_THREAD_INDEX; 386 387 // scan allocated threads to find a runable thread 388 unsigned int thread_id; 389 for ( thread_id = 0 ; thread_id < threads ; thread_id++ ) 375 390 { 376 if ( _get_t ask_slot( x, y, p, task_id, CTX_NORUN_ID ) == 0 )391 if ( _get_thread_slot( x, y, p, thread_id, CTX_NORUN_ID ) == 0 ) 377 392 { 378 ltid = t ask_id;393 ltid = thread_id; 379 394 break; 380 395 } … … 384 399 psched->current = ltid; 385 400 386 // get values from selected t askcontext387 unsigned int sp_value = _get_t ask_slot( x, y, p, ltid, CTX_SP_ID);388 unsigned int sr_value = _get_t ask_slot( x, y, p, ltid, CTX_SR_ID);389 unsigned int ptpr_value = _get_t ask_slot( x, y, p, ltid, CTX_PTPR_ID);390 unsigned int epc_value = _get_t ask_slot( x, y, p, ltid, CTX_ENTRY_ID);401 // get values from selected thread context 402 unsigned int sp_value = _get_thread_slot( x, y, p, ltid, CTX_SP_ID); 403 unsigned int sr_value = _get_thread_slot( x, y, p, ltid, CTX_SR_ID); 404 unsigned int ptpr_value = _get_thread_slot( x, y, p, ltid, CTX_PTPR_ID); 405 unsigned int epc_value = _get_thread_slot( x, y, p, ltid, CTX_ENTRY_ID); 391 406 392 407 #if GIET_DEBUG_INIT -
soft/giet_vm/giet_kernel/switch.s
r301 r709 1 1 /****************************************************************************** 2 * This function receives two arguments that are the current t askcontext3 * (virtual) addresses and the next t askcontext (virtual) address.2 * This function receives two arguments that are the current thread context 3 * (virtual) addresses and the next thread context (virtual) address. 4 4 * 5 5 * This function should be called in a critical section … … 15 15 ******************************************************************************/ 16 16 17 .globl _t ask_switch18 .func _t ask_switch19 .type _t ask_switch, %function17 .globl _thread_switch 18 .func _thread_switch 19 .type _thread_switch, %function 20 20 21 _t ask_switch:21 _thread_switch: 22 22 23 /* save _current taskcontext */24 add $27, $4, $0 /* $27 <= &context[curr _task_id] */23 /* first step : save current thread context */ 24 add $27, $4, $0 /* $27 <= &context[current] */ 25 25 26 26 .set noat … … 70 70 sw $26, 39*4($27) /* ctx[35] <= PTPR */ 71 71 72 /* restore next taskcontext */73 add $27, $5, $0 /* $27<= &context[next _task_id] */72 /* second step : restore next thread context */ 73 add $27, $5, $0 /* $27<= &context[next] */ 74 74 75 75 .set noat … … 123 123 124 124 .endfunc 125 .size _t ask_switch, .-_task_switch125 .size _thread_switch, .-_thread_switch 126 126 -
soft/giet_vm/giet_kernel/sys_handler.c
r707 r709 26 26 #include <io.h> 27 27 28 #if !defined(X_SIZE) 29 # error: You must define X_SIZE in the hard_config.h file 30 #endif 31 32 #if !defined(Y_SIZE) 33 # error: You must define Y_SIZE in the hard_config.h file 34 #endif 35 36 #if !defined(NB_PROCS_MAX) 37 # error: You must define NB_PROCS_MAX in the hard_config.h file 38 #endif 39 28 40 #if !defined(SEG_BOOT_MAPPING_BASE) 29 41 # error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file … … 75 87 extern unsigned int _coproc_mode[X_SIZE*Y_SIZE]; 76 88 extern unsigned int _coproc_error[X_SIZE*Y_SIZE]; 77 extern unsigned int _coproc_gtid[X_SIZE*Y_SIZE]; 78 89 extern unsigned int _coproc_trdid[X_SIZE*Y_SIZE]; 79 90 80 91 // allocated in tty_driver.c file. 81 extern unsigned int _tty_rx_full[NB_TTY_CHANNELS]; 82 extern unsigned int _tty_rx_buf[NB_TTY_CHANNELS]; 92 extern tty_fifo_t _tty_rx_fifo[NB_TTY_CHANNELS]; 83 93 84 94 // allocated in kernel_init.c file 85 95 extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 86 96 87 //////////////////////////////////////////////////////////////////////////// 88 // Channel allocators for peripherals 89 // (TTY[0] is reserved for kernel) 90 //////////////////////////////////////////////////////////////////////////// 91 97 //////////////////////////////////////////////////////////////////////////////// 98 // Channel allocators for multi-channels peripherals 99 // - The array _***_channel_allocator[channel] defines the number of user 100 // threads for a dynamically allocated channel of peripheral ***. 101 // - The array _***_channel_wti[channel] defines the WTI index and the 102 // processor coordinates for the processor receiving the channel WTI. 103 //////////////////////////////////////////////////////////////////////////////// 104 105 #if NB_TTY_CHANNELS 92 106 __attribute__((section(".kdata"))) 93 unsigned int _tty_channel [NB_TTY_CHANNELS] = {1};107 unsigned int _tty_channel_alloc[NB_TTY_CHANNELS] = {0}; 94 108 95 109 __attribute__((section(".kdata"))) 96 unsigned int _tim_channel_allocator = 0; 97 110 unsigned int _tty_channel_wti[NB_TTY_CHANNELS]; 111 #endif 112 113 #if NB_TIM_CHANNELS 98 114 __attribute__((section(".kdata"))) 99 unsigned int _ cma_channel[NB_CMA_CHANNELS]= {0};115 unsigned int _tim_channel_alloc[NB_TIM_CHANNELS] = {0}; 100 116 101 117 __attribute__((section(".kdata"))) 102 unsigned int _nic_rx_channel_allocator = 0; 103 118 unsigned int _tim_channel_wti[NB_TIM_CHANNELS]; 119 #endif 120 121 #if NB_CMA_CHANNELS 104 122 __attribute__((section(".kdata"))) 105 unsigned int _nic_tx_channel_allocator = 0; 123 unsigned int _cma_channel_alloc[NB_CMA_CHANNELS] = {0}; 124 125 __attribute__((section(".kdata"))) 126 unsigned int _cma_channel_wti[NB_CMA_CHANNELS]; 127 #endif 128 129 #if NB_NIC_CHANNELS 130 __attribute__((section(".kdata"))) 131 unsigned int _nic_rx_channel_alloc[NB_NIC_CHANNELS] = {0}; 132 133 __attribute__((section(".kdata"))) 134 unsigned int _nic_rx_channel_wti[NB_NIC_CHANNELS]; 135 136 __attribute__((section(".kdata"))) 137 unsigned int _nic_tx_channel_alloc[NB_NIC_CHANNELS] = {0}; 138 139 __attribute__((section(".kdata"))) 140 unsigned int _nic_tx_channel_wti[NB_NIC_CHANNELS]; 141 #endif 106 142 107 143 //////////////////////////////////////////////////////////////////////////// … … 140 176 &_sys_proc_xyp, /* 0x00 */ 141 177 &_get_proctime, /* 0x01 */ 142 &_sys_ tty_write,/* 0x02 */143 &_sys_ tty_read,/* 0x03 */144 &_sys_ tty_alloc,/* 0x04 */145 &_sys_ tasks_status,/* 0x05 */178 &_sys_procs_number, /* 0x02 */ 179 &_sys_xy_from_ptr, /* 0x03 */ 180 &_sys_ukn, /* 0x04 */ 181 &_sys_ukn, /* 0x05 */ 146 182 &_sys_ukn, /* 0x06 */ 147 183 &_sys_heap_info, /* 0x07 */ 148 &_sys_ local_task_id,/* 0x08 */149 &_sys_ global_task_id,/* 0x09 */184 &_sys_vseg_get_vbase, /* 0x08 */ 185 &_sys_vseg_get_length, /* 0x09 */ 150 186 &_sys_fbf_cma_alloc, /* 0x0A */ 151 187 &_sys_fbf_cma_init_buf, /* 0x0B */ … … 153 189 &_sys_fbf_cma_display, /* 0x0D */ 154 190 &_sys_fbf_cma_stop, /* 0x0E */ 155 &_sys_ task_exit,/* 0x0F */156 157 &_sys_ procs_number,/* 0x10 */191 &_sys_ukn, /* 0x0F */ 192 193 &_sys_applications_status, /* 0x10 */ 158 194 &_sys_fbf_sync_write, /* 0x11 */ 159 195 &_sys_fbf_sync_read, /* 0x12 */ 160 &_sys_ thread_id,/* 0x13 */196 &_sys_ukn, /* 0x13 */ 161 197 &_sys_tim_alloc, /* 0x14 */ 162 198 &_sys_tim_start, /* 0x15 */ … … 164 200 &_sys_kill_application, /* 0x17 */ 165 201 &_sys_exec_application, /* 0x18 */ 166 &_sys_ context_switch,/* 0x19 */167 &_sys_ vseg_get_vbase,/* 0x1A */168 &_sys_ vseg_get_length,/* 0x1B */169 &_sys_ xy_from_ptr,/* 0x1C */170 &_sys_ ukn,/* 0x1D */171 &_sys_ ukn,/* 0x1E */172 &_sys_ ukn,/* 0x1F */202 &_sys_ukn, /* 0x19 */ 203 &_sys_pthread_control, /* 0x1A */ 204 &_sys_pthread_yield, /* 0x1B */ 205 &_sys_pthread_kill, /* 0x1C */ 206 &_sys_pthread_create, /* 0x1D */ 207 &_sys_pthread_join, /* 0x1E */ 208 &_sys_pthread_exit, /* 0x1F */ 173 209 174 210 &_fat_open, /* 0x20 */ 175 &_ sys_fat_read,/* 0x21 */211 &_fat_read, /* 0x21 */ 176 212 &_fat_write, /* 0x22 */ 177 213 &_fat_lseek, /* 0x23 */ … … 195 231 &_sys_nic_stats, /* 0x34 */ 196 232 &_sys_nic_clear, /* 0x35 */ 197 &_sys_ ukn,/* 0x36 */198 &_sys_ ukn,/* 0x37 */199 &_sys_ ukn, /* 0x38 */233 &_sys_tty_write, /* 0x36 */ 234 &_sys_tty_read, /* 0x37 */ 235 &_sys_tty_alloc, /* 0x38 */ 200 236 &_sys_ukn, /* 0x39 */ 201 237 &_sys_ukn, /* 0x3A */ … … 207 243 }; 208 244 245 246 ////////////////////////////////////////////////////////////////////////////// 247 // Applications related syscall handlers 248 ////////////////////////////////////////////////////////////////////////////// 249 250 //////////////////////////////////////////////////////////////////////// 251 // This function is called by the _sys_exec_application function 252 // to reload all data segments contained in an application.elf file. 209 253 //////////////////////////////////////////////////////////////////////// 210 254 static unsigned int _load_writable_segments( mapping_vspace_t* vspace ) 211 255 { 212 #if GIET_DEBUG_SWITCH 256 257 #if GIET_DEBUG_EXEC 213 258 unsigned int gpid = _get_procid(); 214 259 unsigned int cluster_xy = gpid >> P_WIDTH; … … 216 261 unsigned int x = cluster_xy >> Y_WIDTH; 217 262 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 218 if ( _get_proctime() > GIET_DEBUG_ SWITCH)219 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : enters for %s\n",220 x , y , p , vspace->name );263 if ( _get_proctime() > GIET_DEBUG_EXEC ) 264 _printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] " 265 "enters for %s\n", x , y , p , vspace->name ); 221 266 #endif 222 267 … … 224 269 mapping_vseg_t* vseg = _get_vseg_base(header); 225 270 226 // buffer to store one cluster 227 char buf[4096]; 228 229 // open the .elf file associated to vspace 230 unsigned int vseg_id; 231 unsigned int fd = 0; 232 271 unsigned int vseg_id; // vseg index in mapping 272 char buf[4096]; // buffer to store one cluster 273 unsigned int fd = 0; // file descriptor 274 275 // first scan on vsegs in vspace to find the .elf pathname 233 276 for (vseg_id = vspace->vseg_offset; 234 277 vseg_id < (vspace->vseg_offset + vspace->vsegs); 235 278 vseg_id++) 236 279 { 237 if( vseg[vseg_id].type == VSEG_TYPE_ELF)280 if( vseg[vseg_id].type == VSEG_TYPE_ELF ) 238 281 { 282 // open the .elf file associated to vspace 239 283 fd = _fat_open( vseg[vseg_id].binpath , O_RDONLY ); 240 241 #if GIET_DEBUG_SWITCH242 if ( _get_proctime() > GIET_DEBUG_SWITCH )243 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : open %s / fd = %d\n",244 x , y , p , vseg[vseg_id].binpath , fd );245 #endif246 247 284 if ( fd < 0 ) return 1; 248 285 break; 286 287 #if GIET_DEBUG_EXEC 288 if ( _get_proctime() > GIET_DEBUG_EXEC ) 289 _printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] " 290 "open %s / fd = %d\n", x , y , p , vseg[vseg_id].binpath , fd ); 291 #endif 249 292 } 250 293 } 251 294 252 295 // load Elf-Header into buffer from .elf file 253 if ( _fat_lseek( fd, 0, SEEK_SET ) < 0 ) return 1; 254 if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) return 1; 255 256 #if GIET_DEBUG_SWITCH 257 if ( _get_proctime() > GIET_DEBUG_SWITCH ) 258 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : load Elf-Header\n", 259 x , y , p ); 296 if ( _fat_lseek( fd, 0, SEEK_SET ) < 0 ) 297 { 298 _fat_close( fd ); 299 return 1; 300 } 301 if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) 302 { 303 _fat_close( fd ); 304 return 1; 305 } 306 307 #if GIET_DEBUG_EXEC 308 if ( _get_proctime() > GIET_DEBUG_EXEC ) 309 _printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] " 310 "loaded Elf-Header\n", x , y , p ); 260 311 #endif 261 312 … … 266 317 267 318 // load Program-Header-Table from .elf file 268 if ( _fat_lseek( fd, offset, SEEK_SET ) < 0 ) return 1; 269 if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) return 1; 270 271 #if GIET_DEBUG_SWITCH 272 if ( _get_proctime() > GIET_DEBUG_SWITCH ) 273 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : " 274 "load Program-Header-Table\n", x , y , p ); 319 if ( _fat_lseek( fd, offset, SEEK_SET ) < 0 ) 320 { 321 _fat_close( fd ); 322 return 1; 323 } 324 if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) 325 { 326 _fat_close( fd ); 327 return 1; 328 } 329 330 #if GIET_DEBUG_EXEC 331 if ( _get_proctime() > GIET_DEBUG_EXEC ) 332 _printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] " 333 "loaded Program-Header-Table\n", x , y , p ); 275 334 #endif 276 335 … … 278 337 Elf32_Phdr* elf_pht_ptr = (Elf32_Phdr*)buf; 279 338 280 // scan segments to load all loadable & writable segments 281 unsigned int seg_id; 282 for (seg_id = 0 ; seg_id < nsegments ; seg_id++) 283 { 284 if ( (elf_pht_ptr[seg_id].p_type == PT_LOAD) && // loadable 285 (elf_pht_ptr[seg_id].p_flags & PF_W) ) // writable 339 // second scan on vsegs in vspace to load the seg_data segments : 340 // - type == VSEG_TYPE_ELF 341 // - non eXecutable 342 for (vseg_id = vspace->vseg_offset; 343 vseg_id < (vspace->vseg_offset + vspace->vsegs); 344 vseg_id++) 345 { 346 if( (vseg[vseg_id].type == VSEG_TYPE_ELF) && // type ELF 347 ((vseg[vseg_id].mode & 0x4) == 0) ) // non executable 286 348 { 287 // Get segment attributes 288 paddr_t seg_paddr = vseg[vseg_id].pbase; 289 unsigned int seg_offset = elf_pht_ptr[seg_id].p_offset; 290 unsigned int seg_size = elf_pht_ptr[seg_id].p_filesz; 291 292 // load the segment 293 if ( _fat_lseek( fd, seg_offset, SEEK_SET ) < 0 ) return 1; 294 if ( _fat_read( fd, seg_paddr, seg_size, 1 ) < 0 ) return 1; 295 296 #if GIET_DEBUG_SWITCH 297 if ( _get_proctime() > GIET_DEBUG_SWITCH ) 298 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : load segment %x\n", 299 x , y , p , seg_vaddr ); 349 // get vbase and pbase 350 paddr_t pbase = vseg[vseg_id].pbase; 351 unsigned int vbase = vseg[vseg_id].vbase; 352 353 // scan segments in Progam-Header-Table to find match 354 // No match checking as the segment was previously found 355 unsigned int seg; 356 for (seg = 0 ; seg < nsegments ; seg++) 357 { 358 if ( (elf_pht_ptr[seg].p_type == PT_LOAD) && // loadable 359 (elf_pht_ptr[seg].p_flags & PF_W) && // writable 360 (elf_pht_ptr[seg].p_vaddr == vbase) ) // matching 361 { 362 // Get segment offset and size in .elf file 363 unsigned int seg_offset = elf_pht_ptr[seg].p_offset; 364 unsigned int seg_size = elf_pht_ptr[seg].p_filesz; 365 366 // compute destination address and extension for _fat_read() 367 unsigned int dest = (unsigned int)pbase; 368 unsigned int extend = (unsigned int)(pbase>>32) | 0xFFFF0000; 369 370 // load the segment 371 if ( _fat_lseek( fd, seg_offset, SEEK_SET ) < 0 ) 372 { 373 _fat_close( fd ); 374 return 1; 375 } 376 if ( _fat_read( fd, dest, seg_size, extend ) < 0 ) 377 { 378 _fat_close( fd ); 379 return 1; 380 } 381 } 382 } 383 384 #if GIET_DEBUG_EXEC 385 if ( _get_proctime() > GIET_DEBUG_EXEC ) 386 _printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] " 387 "loaded segment %x\n", x , y , p , vbase ); 300 388 #endif 301 389 } … … 308 396 } // end load_writable_segments() 309 397 310 ////////////////////////////////////////////////////////////////////////////// 311 // Applications related syscall handlers 312 ////////////////////////////////////////////////////////////////////////////// 398 399 400 /////////////////////////////////////// 401 int _sys_exec_application( char* name ) 402 { 403 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 404 mapping_vspace_t * vspace = _get_vspace_base(header); 405 mapping_thread_t * thread = _get_thread_base(header); 406 mapping_vseg_t * vseg = _get_vseg_base(header); 407 408 unsigned int vspace_id; 409 unsigned int thread_id; 410 411 #if GIET_DEBUG_EXEC 412 unsigned int gpid = _get_procid(); 413 unsigned int cluster_xy = gpid >> P_WIDTH; 414 unsigned int p = gpid & ((1<<P_WIDTH)-1); 415 unsigned int x = cluster_xy >> Y_WIDTH; 416 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 417 if ( _get_proctime() > GIET_DEBUG_EXEC ) 418 _printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] " 419 "enters for %s at cycle %d\n", x, y, p, name, _get_proctime() ); 420 #endif 421 422 unsigned int y_size = header->y_size; 423 424 // scan vspaces to find matching vspace name 425 for (vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++) 426 { 427 if ( _strcmp( vspace[vspace_id].name, name ) == 0 ) // vspace found 428 { 429 430 #if GIET_DEBUG_EXEC 431 if ( _get_proctime() > GIET_DEBUG_EXEC ) 432 _printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] " 433 "found vspace %s at cycle %d\n", x, y, p, name, _get_proctime() ); 434 #endif 435 // reload writable segments 436 if ( _load_writable_segments( &vspace[vspace_id] ) ) 437 { 438 _printf("[GIET ERROR] _sys_exec_application() : " 439 "can't load data segment for vspace %s\n", name ); 440 return GIET_SYSCALL_CANNOT_LOAD_DATA_SEGMENT; 441 } 442 443 #if GIET_DEBUG_EXEC 444 if ( _get_proctime() > GIET_DEBUG_EXEC ) 445 _printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] " 446 "load segments for vspace %s at cycle %d\n", x, y, p, name, _get_proctime() ); 447 #endif 448 // scan threads in vspace with three goals : 449 // - check all threads desactivated 450 // - re-initialise all threads contexts 451 // - find main thread 452 unsigned int main_found = 0; 453 unsigned int main_ltid = 0; 454 static_scheduler_t* main_psched = NULL; 455 unsigned int min = vspace[vspace_id].thread_offset; 456 unsigned int max = min + vspace[vspace_id].threads; 457 for ( thread_id = min ; thread_id < max ; thread_id++ ) 458 { 459 // get thread identifiers : [x,y,p,ltid] 460 unsigned int cid = thread[thread_id].clusterid; 461 unsigned int x = cid / y_size; 462 unsigned int y = cid % y_size; 463 unsigned int p = thread[thread_id].proclocid; 464 unsigned int ltid = thread[thread_id].ltid; 465 unsigned int vsid = thread[thread_id].stack_vseg_id; 466 467 // get scheduler pointer 468 static_scheduler_t* psched = _schedulers[x][y][p]; 469 470 // check thread non active 471 if ( psched->context[ltid].slot[CTX_NORUN_ID] == 0 ) // runnable !!! 472 { 473 _printf("\n[GIET ERROR] in _sys_exec_application() : " 474 "thread %s already active in vspace %s\n", 475 thread[thread_id].name, name ); 476 return GIET_SYSCALL_THREAD_ALREADY_ACTIVE; 477 } 478 479 // initialise thread context 480 unsigned int ctx_epc = psched->context[ltid].slot[CTX_ENTRY_ID]; 481 unsigned int ctx_sp = vseg[vsid].vbase + vseg[vsid].length; 482 unsigned int ctx_ra = (unsigned int)&_ctx_eret; 483 unsigned int ctx_sr = GIET_SR_INIT_VALUE; 484 485 psched->context[ltid].slot[CTX_EPC_ID] = ctx_epc; 486 psched->context[ltid].slot[CTX_RA_ID] = ctx_ra; 487 psched->context[ltid].slot[CTX_SR_ID] = ctx_sr; 488 psched->context[ltid].slot[CTX_SP_ID] = ctx_sp; 489 490 // register information required to activate main thread 491 // actual activation done when threads initialisation is completed 492 if ( thread[thread_id].is_main ) 493 { 494 main_psched = psched; 495 main_ltid = ltid; 496 main_found = 1; 497 } 498 499 #if GIET_DEBUG_EXEC 500 if ( _get_proctime() > GIET_DEBUG_EXEC ) 501 _printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] " 502 "initialise thread %s at cycle %d\n", 503 x, y, p, thread[thread_id].name, _get_proctime() ); 504 #endif 505 } // end loop on vspace threads 506 507 // activate main thread 508 if ( main_found ) 509 { 510 main_psched->context[main_ltid].slot[CTX_NORUN_ID] = 0; 511 } 512 else 513 { 514 _printf("\n[GIET ERROR] in _sys_exec_application() : " 515 "main not found in vspace %s\n", name ); 516 return GIET_SYSCALL_MAIN_NOT_FOUND; 517 } 518 519 #if GIET_DEBUG_EXEC 520 if ( _get_proctime() > GIET_DEBUG_EXEC ) 521 _printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] " 522 "lauched %s at cycle %d\n", x, y, p, name, _get_proctime() ); 523 #endif 524 return GIET_SYSCALL_OK; 525 } 526 } // end of loop on vspaces 527 528 // vspace not found 529 _printf("\n[GIET ERROR] in _sys_exec_application() : " 530 "vspace %s not found\n", name ); 531 return GIET_SYSCALL_VSPACE_NOT_FOUND; 532 533 } // end _sys_exec_application() 534 313 535 314 536 /////////////////////////////////////// … … 317 539 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 318 540 mapping_vspace_t * vspace = _get_vspace_base(header); 319 mapping_t ask_t * task = _get_task_base(header);541 mapping_thread_t * thread = _get_thread_base(header); 320 542 321 543 unsigned int vspace_id; 322 unsigned int task_id; 323 unsigned int y_size = header->y_size; 544 unsigned int thread_id; 324 545 325 546 #if GIET_DEBUG_EXEC 547 unsigned int gpid = _get_procid(); 548 unsigned int cluster_xy = gpid >> P_WIDTH; 549 unsigned int p = gpid & ((1<<P_WIDTH)-1); 550 unsigned int x = cluster_xy >> Y_WIDTH; 551 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 326 552 if ( _get_proctime() > GIET_DEBUG_EXEC ) 327 _printf("\n[DEBUG EXEC] enters _sys_kill_application() for %s\n", name ); 328 #endif 329 330 // scan vspaces 553 _printf("\n[DEBUG EXEC] _sys_kill_application() P[%d,%d,%d] " 554 "enters at cycle %d for %s\n", x, y, p, _get_proctime() , name ); 555 #endif 556 557 // shell cannot be killed 558 if ( _strcmp( name , "shell" ) == 0 ) 559 { 560 _printf("\n[GIET ERROR] in _sys_kill_application() : " 561 "%s application cannot be killed\n", name ); 562 return GIET_SYSCALL_APPLI_CANNOT_BE_KILLED; 563 } 564 565 // scan vspaces to find matching vspace name 331 566 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 332 567 { 333 568 if ( _strcmp( vspace[vspace_id].name, name ) == 0 ) 334 569 { 335 // check if application can be killed 336 if ( vspace[vspace_id].active ) return -2; 337 338 // scan tasks in vspace 339 for (task_id = vspace[vspace_id].task_offset; 340 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 341 task_id++) 570 // scan threads to send KILL signal to all threads in vspace 571 unsigned int y_size = header->y_size; 572 unsigned int min = vspace[vspace_id].thread_offset; 573 unsigned int max = min + vspace[vspace_id].threads; 574 for ( thread_id = min ; thread_id < max ; thread_id++ ) 342 575 { 343 unsigned int cid = t ask[task_id].clusterid;576 unsigned int cid = thread[thread_id].clusterid; 344 577 unsigned int x = cid / y_size; 345 578 unsigned int y = cid % y_size; 346 unsigned int p = t ask[task_id].proclocid;347 unsigned int ltid = t ask[task_id].ltid;348 349 // get scheduler pointer for processor running the t ask579 unsigned int p = thread[thread_id].proclocid; 580 unsigned int ltid = thread[thread_id].ltid; 581 582 // get scheduler pointer for processor running the thread 350 583 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 351 584 352 585 // set KILL signal bit 353 _atomic_or( &psched->context[ltid] [CTX_SIG_ID] , SIG_MASK_KILL );586 _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL ); 354 587 } 355 588 356 589 #if GIET_DEBUG_EXEC 357 590 if ( _get_proctime() > GIET_DEBUG_EXEC ) 358 _printf("\n[DEBUG EXEC] exit _sys_kill_application() : %s will be killed\n", name ); 359 #endif 360 361 return 0; 591 _printf("\n[DEBUG EXEC] _sys_kill_application() P[%d,%d,%d] " 592 "kill %s at cycle %d\n", x, y, p, name, _get_proctime() ); 593 #endif 594 595 return GIET_SYSCALL_OK; 362 596 } 363 } 597 } // en loop on vspaces 598 599 _printf("\n[GIET ERROR] in _sys_kill_application() : " 600 "application %s not found\n", name ); 601 return GIET_SYSCALL_VSPACE_NOT_FOUND; 602 603 } // end _sys_kill_application() 604 605 606 607 ////////////////////////////// 608 int _sys_applications_status() 609 { 610 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 611 mapping_thread_t * thread = _get_thread_base(header); 612 mapping_vspace_t * vspace = _get_vspace_base(header); 613 mapping_cluster_t * cluster = _get_cluster_base(header); 614 615 unsigned int thread_id; 616 unsigned int vspace_id; 617 618 // scan all vspaces 619 for( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ ) 620 { 621 _user_printf("\n*** vspace %s\n", vspace[vspace_id].name ); 622 623 // scan all threads in vspace 624 unsigned int min = vspace[vspace_id].thread_offset ; 625 unsigned int max = min + vspace[vspace_id].threads ; 626 for ( thread_id = min ; thread_id < max ; thread_id++ ) 627 { 628 unsigned int clusterid = thread[thread_id].clusterid; 629 unsigned int p = thread[thread_id].proclocid; 630 unsigned int x = cluster[clusterid].x; 631 unsigned int y = cluster[clusterid].y; 632 unsigned int ltid = thread[thread_id].ltid; 633 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 634 unsigned int norun = psched->context[ltid].slot[CTX_NORUN_ID]; 635 unsigned int tty = psched->context[ltid].slot[CTX_TTY_ID]; 636 unsigned int current = psched->current; 637 638 if ( current == ltid ) 639 _user_printf(" - thread %s / P[%d,%d,%d] / ltid = %d / " 640 "TTY = %d / norun = %x : running\n", 641 thread[thread_id].name, x, y, p, ltid, tty, norun ); 642 else if ( norun == 0 ) 643 _user_printf(" - thread %s / P[%d,%d,%d] / ltid = %d / " 644 "TTY = %d / norun = %x : runable\n", 645 thread[thread_id].name, x, y, p, ltid, tty, norun); 646 else 647 _user_printf(" - thread %s / P[%d,%d,%d] / ltid = %d / " 648 "TTY = %d / norun = %x : blocked\n", 649 thread[thread_id].name, x, y, p, ltid, tty, norun); 650 } 651 } 652 _user_printf("\n"); 653 return GIET_SYSCALL_OK; 654 } // end _sys_applications_status() 655 656 657 658 ///////////////////////////////////////////////////////////////////////////// 659 // Threads related syscall handlers 660 ///////////////////////////////////////////////////////////////////////////// 661 662 //////////////////////////////////////////////// 663 int _sys_pthread_create( unsigned int* buffer, 664 void* attr, 665 void* function, 666 void* arg ) 667 { 668 // attr argument not supported 669 if ( attr != NULL ) 670 { 671 _printf("\n[GIET ERROR] in _sys_pthread_create() : " 672 "attr argument not supported\n" ); 673 674 return GIET_SYSCALL_PTHREAD_ARGUMENT_NOT_SUPPORTED; 675 } 676 677 // get pointers in mapping 678 mapping_header_t* header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 679 mapping_thread_t* thread = _get_thread_base(header); 680 mapping_vspace_t* vspace = _get_vspace_base(header); 681 mapping_cluster_t* cluster = _get_cluster_base(header); 682 683 // get scheduler for processor running the calling thread 684 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 685 686 // get calling thread local index in scheduler 687 unsigned int current = psched->current; 688 689 // get vspace index 690 unsigned int vspace_id = psched->context[current].slot[CTX_VSID_ID]; 364 691 365 692 #if GIET_DEBUG_EXEC 366 693 if ( _get_proctime() > GIET_DEBUG_EXEC ) 367 _printf("\n[DEBUG EXEC] exit _sys_kill_application() : %s not found\n", name ); 368 #endif 369 370 return -1; // not found 371 372 } // end _sys_kill_application() 694 _printf("\n[DEBUG EXEC] _sys_pthread_create() : enters at cycle %d" 695 " for vspace %s / entry = %x\n", 696 _get_proctime() , vspace[vspace_id].name , (unsigned int)function ); 697 #endif 698 699 unsigned int thread_id; // searched thread : local index in mapping 700 unsigned int clusterid; // searched thread : cluster index 701 unsigned int lpid; // searched thread : processor local index 702 unsigned int ltid; // searched thread : scheduler thread index 703 unsigned int cx; // searched thread : X coordinate for searched thread 704 unsigned int cy; // searched thread : Y coordinate for searched thread 705 unsigned int entry; // searched thread : entry point 706 unsigned int norun; // searched thread : norun vector 707 unsigned int trdid; // searched thread : thread identifier 708 709 // scan threads in vspace to find an inactive thread matching function 710 unsigned int min = vspace[vspace_id].thread_offset; 711 unsigned int max = min + vspace[vspace_id].threads; 712 unsigned int found = 0; 713 for ( thread_id = min ; (thread_id < max) && (found == 0) ; thread_id++ ) 714 { 715 // get thread coordinates [cx,cy,lpid] and ltid from mapping 716 ltid = thread[thread_id].ltid; 717 clusterid = thread[thread_id].clusterid; 718 lpid = thread[thread_id].proclocid; 719 cx = cluster[clusterid].x; 720 cy = cluster[clusterid].y; 721 722 // get thread scheduler pointer 723 psched = _schedulers[cx][cy][lpid]; 724 725 // get thread entry-point, norun-vector, and trdid from context 726 entry = psched->context[ltid].slot[CTX_ENTRY_ID]; 727 norun = psched->context[ltid].slot[CTX_NORUN_ID]; 728 trdid = psched->context[ltid].slot[CTX_TRDID_ID]; 729 730 // check matching 731 if ( ((unsigned int)function == entry ) && 732 (norun & NORUN_MASK_THREAD) ) found = 1; 733 734 } // end loop on threads 735 736 if ( found ) // one matching inactive thread has been found 737 { 738 // set argument value in thread context 739 if ( arg != NULL ) psched->context[ltid].slot[CTX_A0_ID] = (unsigned int)arg; 740 741 // activate thread 742 psched->context[ltid].slot[CTX_NORUN_ID] = 0; 743 744 // return launched thead global identifier 745 *buffer = trdid; 746 747 #if GIET_DEBUG_EXEC 748 if ( _get_proctime() > GIET_DEBUG_EXEC ) 749 _printf("\n[DEBUG EXEC] exit _sys_pthread_create() at cycle %d : thread %x launched\n", 750 _get_proctime() , trdid); 751 #endif 752 return GIET_SYSCALL_OK; 753 } 754 else // no matching thread found 755 { 756 _printf("\n[GIET ERROR] in _sys_pthread_create() : " 757 "no matching thread for entry = %x in vspace %s\n", 758 (unsigned int)function , vspace[vspace_id].name ); 759 760 return GIET_SYSCALL_THREAD_NOT_FOUND; 761 } 762 763 } // end _sys_pthread_create() 764 765 766 /////////////////////////////////////////// 767 int _sys_pthread_join( unsigned int trdid, 768 void* ptr ) 769 { 770 // ptr argument not supported 771 if ( ptr != NULL ) 772 { 773 _printf("\n[GIET ERROR] in _sys_pthread_join() : " 774 "ptr argument not supported, must be NULL\n" ); 775 776 return GIET_SYSCALL_PTHREAD_ARGUMENT_NOT_SUPPORTED; 777 } 778 779 780 #if GIET_DEBUG_EXEC 781 if ( _get_proctime() > GIET_DEBUG_EXEC ) 782 _printf("\n[DEBUG EXEC] enters _sys_pthread_join() at cycle %d for thread %x\n", 783 _get_proctime() , trdid ); 784 #endif 785 786 // get calling thread vspace 787 unsigned int caller_vspace = _get_context_slot( CTX_VSID_ID ); 788 789 // get and check target thread indexes from trdid 790 unsigned int cx = (trdid>>24) & 0xFF; 791 unsigned int cy = (trdid>>16) & 0xFF; 792 unsigned int lpid = (trdid>>8 ) & 0xFF; 793 unsigned int ltid = (trdid ) & 0xFF; 794 795 // get target thread scheduler, vspace and registered trdid 796 static_scheduler_t* psched = _schedulers[cx][cy][lpid]; 797 unsigned int target_vspace = psched->context[ltid].slot[CTX_VSID_ID]; 798 unsigned int registered_trdid = psched->context[ltid].slot[CTX_TRDID_ID]; 799 800 // check trdid 801 if ( trdid != registered_trdid ) 802 { 803 _printf("\nerror in _sys_pthread_join() : " 804 "trdid = %x / registered_trdid = %x\n", 805 trdid , registered_trdid ); 806 807 return GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT; 808 } 809 810 // check calling thread and target thread in same vspace 811 if ( caller_vspace != target_vspace ) 812 { 813 _printf("\n[GIET ERROR] in _sys_pthread_join() : " 814 " calling thread and target thread not in same vspace\n"); 815 816 return GIET_SYSCALL_NOT_IN_SAME_VSPACE; 817 } 818 819 // get target thread state 820 unsigned int* pnorun = &psched->context[ltid].slot[CTX_NORUN_ID]; 821 822 asm volatile ( "2000: \n" 823 "move $11, %0 \n" /* $11 <= ptr */ 824 "lw $11, 0($11) \n" /* $11 <= M[ptr] */ 825 "andi $11, $11, 1 \n" /* $11 <= norun & 0x1 */ 826 "beqz $11, 2000b \n" 827 : 828 : "r" (pnorun) 829 : "$11" ); 830 831 return GIET_SYSCALL_OK; 832 833 } // end _sys_pthread_join() 834 835 836 //////////////////////////////////////// 837 int _sys_pthread_kill( pthread_t trdid, 838 int signal ) 839 { 840 // get calling thread vspace 841 unsigned int caller_vspace = _get_context_slot( CTX_VSID_ID ); 842 843 // get and check target thread indexes from trdid 844 unsigned int cx = (trdid>>24) & 0xFF; 845 unsigned int cy = (trdid>>16) & 0xFF; 846 unsigned int lpid = (trdid>>8 ) & 0xFF; 847 unsigned int ltid = (trdid ) & 0xFF; 848 849 // get target thread scheduler, vspace and registered trdid 850 static_scheduler_t* psched = _schedulers[cx][cy][lpid]; 851 unsigned int target_vspace = psched->context[ltid].slot[CTX_VSID_ID]; 852 unsigned int registered_trdid = psched->context[ltid].slot[CTX_TRDID_ID]; 853 854 // check trdid 855 if ( trdid != registered_trdid ) 856 { 857 _printf("\n[GIET ERROR] in _sys_pthread_kill() : trdid = %x" 858 " / registered_trdid = %x\n", trdid , registered_trdid ); 859 return GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT; 860 } 861 862 // check calling thread and target thread in same vspace 863 if ( caller_vspace != target_vspace ) 864 { 865 _printf("\n[GIET ERROR] in _sys_pthread_kill() : not in same vspace\n"); 866 return GIET_SYSCALL_NOT_IN_SAME_VSPACE; 867 } 868 869 // register KILL signal in target thread context if required 870 if ( signal ) 871 { 872 _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL ); 873 } 874 875 return GIET_SYSCALL_OK; 876 877 } // end _sys_pthread_kill() 878 879 880 ///////////////////////////////////// 881 int _sys_pthread_exit( void* string ) 882 { 883 unsigned int date = _get_proctime(); 884 885 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 886 mapping_vspace_t * vspace = _get_vspace_base(header); 887 888 unsigned int ltid = _get_context_slot(CTX_LTID_ID); 889 unsigned int trdid = _get_context_slot(CTX_TRDID_ID); 890 unsigned int vsid = _get_context_slot(CTX_VSID_ID); 891 892 // print exit message 893 if ( string == NULL ) 894 { 895 _printf("\n[GIET WARNING] Exit thread %x in vspace %s at cycle %d\n", 896 trdid , vspace[vsid].name , date ); 897 } 898 else 899 { 900 _printf("\n[GIET WARNING] Exit thread %x in vspace %s at cycle %d\n" 901 " Cause : %s\n\n", 902 trdid , vspace[vsid].name , date , (char*) string ); 903 } 373 904 374 /////////////////////////////////////// 375 int _sys_exec_application( char* name ) 376 { 377 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 378 mapping_vseg_t * vseg = _get_vseg_base(header); 379 mapping_vspace_t * vspace = _get_vspace_base(header); 380 mapping_task_t * task = _get_task_base(header); 381 382 unsigned int vspace_id; 383 unsigned int task_id; 384 unsigned int y_size = header->y_size; 385 386 #if GIET_DEBUG_EXEC 905 // get scheduler pointer for calling thread 906 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 907 908 // register KILL signal in calling thread context (suicid request) 909 _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL ); 910 911 // deschedule calling thread 912 unsigned int save_sr; 913 _it_disable( &save_sr ); 914 915 _ctx_switch(); 916 917 return GIET_SYSCALL_OK; 918 919 } // end _sys_pthread_exit() 920 921 //////////////////////// 922 int _sys_pthread_yield() 923 { 924 unsigned int save_sr; 925 926 _it_disable( &save_sr ); 927 _ctx_switch(); 928 _it_restore( &save_sr ); 929 930 return GIET_SYSCALL_OK; 931 } 932 933 ////////////////////////////////////////////////// 934 int _sys_pthread_control( unsigned int command, 935 char* vspace_name, 936 char* thread_name ) 937 { 938 939 #if GIET_DEBUG_EXEC 387 940 if ( _get_proctime() > GIET_DEBUG_EXEC ) 388 _printf("\n[DEBUG EXEC] enters _sys_exec_application() at cycle %d for %s\n", 389 _get_proctime() , name ); 390 #endif 391 392 // find vspace 393 for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ ) 394 { 395 if ( _strcmp( vspace[vspace_id].name, name ) == 0 ) 941 _printf("\n[DEBUG EXEC] _sys_pthread_control() at cycle %d : " 942 "enter for vspace %s / thread %s / command = %d\n", 943 _get_proctime() , vspace_name, thread_name, command ); 944 #endif 945 946 // get pointers in mapping 947 mapping_header_t* header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 948 mapping_thread_t* thread = _get_thread_base(header); 949 mapping_vspace_t* vspace = _get_vspace_base(header); 950 mapping_cluster_t* cluster = _get_cluster_base(header); 951 952 unsigned int found; 953 954 // search vspace name to get vspace index: vsid 955 found = 0; 956 unsigned int vsid; 957 for( vsid = 0 ; vsid < header->vspaces ; vsid++ ) 958 { 959 if ( _strcmp( vspace[vsid].name, vspace_name ) == 0 ) 960 { 961 found = 1; 396 962 break; 397 } 398 399 if ( vspace_id == header->vspaces ) 400 { 401 _printf("\n[GIET ERROR] _sys_exec_application() : %s not found\n", name ); 402 return -1; 403 } 404 405 // scan tasks in vspace 406 for (task_id = vspace[vspace_id].task_offset; 407 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 408 task_id++) 409 { 410 unsigned int cid = task[task_id].clusterid; 411 unsigned int x = cid / y_size; 412 unsigned int y = cid % y_size; 413 unsigned int p = task[task_id].proclocid; 414 unsigned int ltid = task[task_id].ltid; 415 416 // get scheduler pointer for processor running the task 417 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 418 419 // check if an application task is runnable 420 if ( psched->context[ltid][CTX_NORUN_ID] == 0 ) 963 } 964 } 965 966 if ( found == 0 ) return GIET_SYSCALL_VSPACE_NOT_FOUND; 967 968 // search thread name in vspace to get thread index: tid 969 found = 0; 970 unsigned int tid; 971 unsigned int min = vspace[vsid].thread_offset; 972 unsigned int max = min + vspace[vsid].threads; 973 for( tid = min ; tid < max ; tid++ ) 974 { 975 if ( _strcmp( thread[tid].name, thread_name ) == 0 ) 421 976 { 422 _printf( "\n[GIET ERROR] _sys_exec_application() : %s already executed\n", name );423 return -2;977 found = 1; 978 break; 424 979 } 425 980 } 426 981 427 // reload writable segments 428 if ( _load_writable_segments( &vspace[vspace_id] ) ) 429 { 430 _printf("[GIET ERROR] _sys_exec_application() : can't load segments for %s\n", name ); 431 return -3; 432 } 433 434 // scan tasks in vspace 435 for (task_id = vspace[vspace_id].task_offset; 436 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 437 task_id++) 438 { 439 unsigned int cid = task[task_id].clusterid; 440 unsigned int x = cid / y_size; 441 unsigned int y = cid % y_size; 442 unsigned int p = task[task_id].proclocid; 443 unsigned int ltid = task[task_id].ltid; 444 445 // get scheduler pointer for processor running the task 446 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 447 448 // reset task context: RA / SR / SP / EPC / NORUN 449 unsigned int vseg_id = task[task_id].stack_vseg_id; 450 unsigned int sp_value = vseg[vseg_id].vbase + vseg[vseg_id].length; 451 452 psched->context[ltid][CTX_RA_ID] = (unsigned int)&_ctx_eret; 453 psched->context[ltid][CTX_SR_ID] = GIET_SR_INIT_VALUE; 454 psched->context[ltid][CTX_SP_ID] = sp_value; 455 psched->context[ltid][CTX_EPC_ID] = psched->context[ltid][CTX_ENTRY_ID]; 456 psched->context[ltid][CTX_NORUN_ID] = 0; 457 } 458 459 #if GIET_DEBUG_EXEC 460 if ( _get_proctime() > GIET_DEBUG_EXEC ) 461 _printf("\n[DEBUG EXEC] exit _sys_exec_application() at cycle %d : %s will be executed\n", 462 _get_proctime() , name ); 463 #endif 464 465 return 0; 466 } // end _sys_exec_application() 467 982 if ( found == 0 ) return GIET_SYSCALL_THREAD_NOT_FOUND; 983 984 // get thread coordinates 985 unsigned int cid = thread[tid].clusterid; 986 unsigned int x = cluster[cid].x; 987 unsigned int y = cluster[cid].y; 988 unsigned int p = thread[tid].proclocid; 989 unsigned int ltid = thread[tid].ltid; 990 991 static_scheduler_t* psched = _schedulers[x][y][p]; 992 993 // check trdid and vsid 994 unsigned int trdid = x<<24 | y<<16 | p<<8 | ltid; 995 if ( (psched->context[ltid].slot[CTX_TRDID_ID] != trdid) || 996 (psched->context[ltid].slot[CTX_VSID_ID] != vsid) ) 997 return GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT; 998 999 // execute command 1000 if ( command == THREAD_CMD_PAUSE ) 1001 { 1002 _atomic_or ( &psched->context[ltid].slot[CTX_NORUN_ID], NORUN_MASK_THREAD ); 1003 return GIET_SYSCALL_OK; 1004 } 1005 else if ( command == THREAD_CMD_RESUME ) 1006 { 1007 _atomic_and( &psched->context[ltid].slot[CTX_NORUN_ID], ~NORUN_MASK_THREAD ); 1008 return GIET_SYSCALL_OK; 1009 } 1010 else if ( command == THREAD_CMD_CONTEXT ) 1011 { 1012 _user_printf( " - CTX_TRDID = %x\n" 1013 " - CTX_VSID = %x\n" 1014 " - CTX_EPC = %x\n" 1015 " - CTX_PTAB = %x\n" 1016 " - CTX_PTPR = %x\n" 1017 " - CTX_SR = %x\n" 1018 " - CTX_RA = %x\n" 1019 " - CTX_SP = %x\n" 1020 " - CTX_ENTRY = %x\n" 1021 " - CTX_NORUN = %x\n" 1022 " - CTX_SIGS = %x\n" 1023 " - CTX_LOCKS = %x\n" 1024 " - CTX_TTY = %x\n" 1025 " - CTX_NIC_RX = %x\n" 1026 " - CTX_NIC_TX = %x\n" 1027 " - CTX_CMA_RX = %x\n" 1028 " - CTX_CMA_TX = %x\n" 1029 " - CTX_CMA_FB = %x\n", 1030 psched->context[ltid].slot[CTX_TRDID_ID], 1031 psched->context[ltid].slot[CTX_VSID_ID], 1032 psched->context[ltid].slot[CTX_EPC_ID], 1033 psched->context[ltid].slot[CTX_PTAB_ID], 1034 psched->context[ltid].slot[CTX_PTPR_ID], 1035 psched->context[ltid].slot[CTX_SR_ID], 1036 psched->context[ltid].slot[CTX_RA_ID], 1037 psched->context[ltid].slot[CTX_SP_ID], 1038 psched->context[ltid].slot[CTX_ENTRY_ID], 1039 psched->context[ltid].slot[CTX_NORUN_ID], 1040 psched->context[ltid].slot[CTX_SIGS_ID], 1041 psched->context[ltid].slot[CTX_LOCKS_ID], 1042 psched->context[ltid].slot[CTX_TTY_ID], 1043 psched->context[ltid].slot[CTX_NIC_RX_ID], 1044 psched->context[ltid].slot[CTX_NIC_TX_ID], 1045 psched->context[ltid].slot[CTX_CMA_RX_ID], 1046 psched->context[ltid].slot[CTX_CMA_TX_ID], 1047 psched->context[ltid].slot[CTX_CMA_FB_ID] ); 1048 return GIET_SYSCALL_OK; 1049 } 1050 else 1051 { 1052 return GIET_SYSCALL_ILLEGAL_THREAD_COMMAND_TYPE; 1053 } 1054 1055 } // end _sys_pthread_control() 1056 1057 1058 468 1059 469 1060 ////////////////////////////////////////////////////////////////////////////// … … 476 1067 { 477 1068 // In this implementation, the allocation policy is constrained: 478 // the coprocessor must be in the same cluster as the calling t ask,1069 // the coprocessor must be in the same cluster as the calling thread, 479 1070 // and there is at most one coprocessor per cluster 480 1071 … … 519 1110 *coproc_info = _coproc_info[cluster_id]; 520 1111 521 // register coprocessor coordinates in t askcontext1112 // register coprocessor coordinates in thread context 522 1113 unsigned int cluster_xy = (x<<Y_WIDTH) + y; 523 1114 _set_context_slot( CTX_COPROC_ID , cluster_xy ); … … 528 1119 x , y , *coproc_info , cluster_xy ); 529 1120 #endif 530 return 0;1121 return GIET_SYSCALL_OK; 531 1122 } 532 1123 else … … 535 1126 " with type %d available in cluster[%d,%d]\n", 536 1127 coproc_type , x , y ); 537 return -1;1128 return GIET_SYSCALL_COPROCESSOR_NOT_FOUND; 538 1129 } 539 1130 } // end _sys_coproc_alloc() … … 553 1144 { 554 1145 _printf("\n[GIET_ERROR] in _sys_coproc_release(): " 555 "no coprocessor allocated to t askrunning on P[%d,%d,%d]\n",1146 "no coprocessor allocated to thread running on P[%d,%d,%d]\n", 556 1147 x , y , p ); 557 return -1;1148 return GIET_SYSCALL_COPROCESSOR_NOT_FOUND; 558 1149 } 559 1150 … … 573 1164 } 574 1165 575 // deallocates coprocessor coordinates in t askcontext1166 // deallocates coprocessor coordinates in thread context 576 1167 _set_context_slot( CTX_COPROC_ID , 0xFFFFFFFF ); 577 1168 … … 584 1175 #endif 585 1176 586 return 0;1177 return GIET_SYSCALL_OK; 587 1178 } // end _sys_coproc_release() 588 1179 … … 602 1193 { 603 1194 _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): " 604 "no coprocessor allocated to t askrunning on P[%d,%d,%d]\n",1195 "no coprocessor allocated to thread running on P[%d,%d,%d]\n", 605 1196 x , y , p ); 606 return -1;1197 return GIET_SYSCALL_COPROCESSOR_NOT_FOUND; 607 1198 } 608 1199 … … 615 1206 _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): " 616 1207 " illegal mode\n"); 617 return -1;1208 return GIET_SYSCALL_COPROCESSOR_ILLEGAL_MODE; 618 1209 } 619 1210 … … 622 1213 623 1214 // physical addresses 624 paddr_tbuffer_paddr;1215 unsigned long long buffer_paddr; 625 1216 unsigned int buffer_lsb; 626 1217 unsigned int buffer_msb; 627 paddr_tmwmr_paddr = 0;1218 unsigned long long mwmr_paddr = 0; 628 1219 unsigned int mwmr_lsb; 629 1220 unsigned int mwmr_msb; 630 paddr_tlock_paddr = 0;1221 unsigned long long lock_paddr = 0; 631 1222 unsigned int lock_lsb; 632 1223 unsigned int lock_msb; … … 674 1265 #endif 675 1266 676 return 0;1267 return GIET_SYSCALL_OK; 677 1268 } // end _sys_coproc_channel_init() 678 1269 … … 691 1282 { 692 1283 _printf("\n[GIET_ERROR] in _sys_coproc_run(): " 693 "no coprocessor allocated to t askrunning on P[%d,%d,%d]\n",1284 "no coprocessor allocated to thread running on P[%d,%d,%d]\n", 694 1285 x , y , p ); 695 return -1 ;1286 return -1111; 696 1287 } 697 1288 … … 719 1310 _printf("\n[GIET_ERROR] P[%d,%d,%d] in _sys_coproc_run() for coprocessor[%d,%d]\n" 720 1311 " all channels don't have the same mode\n", x , y , p , cx , cy ); 721 return -1 ;1312 return -1111; 722 1313 } 723 1314 } … … 745 1336 #endif 746 1337 747 return 0;1338 return GIET_SYSCALL_OK; 748 1339 } 749 1340 /////////////////////////////////////////////////////////////////////////// 750 1341 else // mode == MODE_DMA_IRQ => descheduling 751 1342 { 752 // set _coproc_ gtid753 unsigned int ltid = _get_ current_task_id();754 _coproc_ gtid[cluster_id] = (procid<<16) + ltid;1343 // set _coproc_trdid 1344 unsigned int ltid = _get_thread_ltid(); 1345 _coproc_trdid[cluster_id] = (x<<24) + (y<<16) + (p<<8) + ltid; 755 1346 756 1347 // enters critical section … … 760 1351 // set NORUN_MASK_COPROC bit 761 1352 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 762 unsigned int* ptr = &psched->context[ltid] [CTX_NORUN_ID];1353 unsigned int* ptr = &psched->context[ltid].slot[CTX_NORUN_ID]; 763 1354 _atomic_or( ptr , NORUN_MASK_COPROC ); 764 1355 … … 771 1362 #endif 772 1363 773 // deschedule t ask1364 // deschedule thread 774 1365 _ctx_switch(); 775 1366 … … 802 1393 { 803 1394 _printf("\n[GIET_ERROR] in _sys_coproc_completed(): " 804 "no coprocessor allocated to t askrunning on P[%d,%d,%d]\n",1395 "no coprocessor allocated to thread running on P[%d,%d,%d]\n", 805 1396 x , y , p ); 806 return -1 ;1397 return -1111; 807 1398 } 808 1399 … … 879 1470 int _sys_tty_alloc( unsigned int shared ) 880 1471 { 881 unsigned int channel; 882 1472 unsigned int channel; // allocated TTY channel 1473 1474 // get trdid and vsid for the calling thread 1475 unsigned int vsid = _get_context_slot( CTX_VSID_ID ); 1476 unsigned int trdid = _get_thread_trdid(); 1477 1478 // check no TTY already allocated to calling thread 883 1479 if ( _get_context_slot( CTX_TTY_ID ) < NB_TTY_CHANNELS ) 884 1480 { 885 _printf("\n[GIET_ERROR] in _sys_tty_alloc() : TTY channel already allocated\n"); 886 return 0; 887 } 888 889 // get a new TTY channel 1481 _printf("\n[GIET_ERROR] in _sys_tty_alloc() : " 1482 "TTY channel already allocated to thread %x\n", trdid ); 1483 return -1111; 1484 } 1485 1486 mapping_header_t *header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 1487 mapping_vspace_t *vspace = _get_vspace_base(header); 1488 mapping_thread_t *thread = _get_thread_base(header); 1489 1490 // compute number of users 1491 unsigned int users; 1492 if ( shared ) users = vspace[vsid].threads; 1493 else users = 1; 1494 1495 // get a TTY channel 890 1496 for ( channel = 0 ; channel < NB_TTY_CHANNELS ; channel++ ) 891 1497 { 892 if ( !_tty_channel[channel] ) 893 { 894 _tty_channel[channel] = 1; 895 break; 896 } 1498 unsigned int* palloc = &_tty_channel_alloc[channel]; 1499 1500 if ( _atomic_test_and_set( palloc , users ) == 0 ) break; 897 1501 } 898 1502 if ( channel >= NB_TTY_CHANNELS ) 899 1503 { 900 _printf("\n[GIET_ERROR] in _sys_tty_alloc() : no TTY channel available\n"); 901 return -1; 902 } 903 904 // reset kernel buffer for allocated TTY channel 905 _tty_rx_full[channel] = 0; 1504 _printf("\n[GIET_ERROR] in _sys_tty_alloc() : " 1505 "no TTY channel available for thread %x\n", trdid ); 1506 return -1111; 1507 } 1508 1509 // initialise allocated TTY channel 1510 _tty_init( channel ); 906 1511 907 1512 // allocate a WTI mailbox to the calling proc if external IRQ 908 unsigned int unused; 909 if ( USE_PIC ) _ext_irq_alloc( ISR_TTY_RX , channel , &unused ); 1513 unsigned int wti_id; 1514 if ( USE_PIC ) _ext_irq_alloc( ISR_TTY_RX , channel , &wti_id ); 1515 1516 // register wti_id and coordinates for processor receiving WTI 1517 unsigned int procid = _get_procid(); 1518 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 1519 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 1520 unsigned int p = procid & ((1<<P_WIDTH)-1); 1521 _tty_channel_wti[channel] = x<<24 | y<<16 | p<<8 | wti_id; 910 1522 911 1523 // update CTX_TTY_ID 912 if ( shared ) // for all tasks in the same vspace 913 { 914 unsigned int vspace_id = _get_context_slot( CTX_VSID_ID ); 915 mapping_header_t *header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 916 mapping_vspace_t *vspace = _get_vspace_base(header); 917 mapping_task_t *task = _get_task_base(header); 918 919 // scan tasks in vspace 920 unsigned int task_id; 921 for (task_id = vspace[vspace_id].task_offset; 922 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 923 task_id++) 1524 if ( shared ) // for all threads in vspace 1525 { 1526 // scan threads in vspace 1527 unsigned int tid; 1528 for (tid = vspace[vsid].thread_offset; 1529 tid < (vspace[vsid].thread_offset + vspace[vsid].threads); 1530 tid++) 924 1531 { 925 1532 unsigned int y_size = header->y_size; 926 unsigned int cid = t ask[task_id].clusterid;1533 unsigned int cid = thread[tid].clusterid; 927 1534 unsigned int x = cid / y_size; 928 1535 unsigned int y = cid % y_size; 929 unsigned int p = t ask[task_id].proclocid;930 unsigned int ltid = t ask[task_id].ltid;1536 unsigned int p = thread[tid].proclocid; 1537 unsigned int ltid = thread[tid].ltid; 931 1538 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 932 1539 933 // don't overwrite TTY_ID 934 if ( psched->context[ltid][CTX_TTY_ID] >= NB_TTY_CHANNELS ) 935 { 936 psched->context[ltid][CTX_TTY_ID] = channel; 937 } 1540 psched->context[ltid].slot[CTX_TTY_ID] = channel; 938 1541 } 939 1542 } 940 else // for calling t askonly1543 else // for calling thread only 941 1544 { 942 1545 _set_context_slot( CTX_TTY_ID, channel ); 943 1546 } 944 1547 945 return 0; 946 } 947 948 ///////////////////////////////////////// 949 // NOTE: not a syscall 950 int _sys_tty_release() 1548 return GIET_SYSCALL_OK; 1549 } // end _sys_tty_alloc() 1550 1551 ////////////////////// 1552 int _sys_tty_release() // NOTE: not a syscall 951 1553 { 952 1554 unsigned int channel = _get_context_slot( CTX_TTY_ID ); … … 954 1556 if ( channel == -1 ) 955 1557 { 956 _printf("\n[GIET_ERROR] in _sys_tty_release() : TTY channel already released\n"); 957 return -1; 958 } 959 960 // release WTI mailbox 961 if ( USE_PIC ) _ext_irq_release( ISR_TTY_RX , channel ); 962 963 // reset CTX_TTY_ID for all tasks in vspace 964 unsigned int vspace_id = _get_context_slot( CTX_VSID_ID ); 965 mapping_header_t *header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 966 mapping_vspace_t *vspace = _get_vspace_base(header); 967 mapping_task_t *task = _get_task_base(header); 968 969 unsigned int task_id; 970 for (task_id = vspace[vspace_id].task_offset; 971 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 972 task_id++) 973 { 974 unsigned int y_size = header->y_size; 975 unsigned int cid = task[task_id].clusterid; 976 unsigned int x = cid / y_size; 977 unsigned int y = cid % y_size; 978 unsigned int p = task[task_id].proclocid; 979 unsigned int ltid = task[task_id].ltid; 980 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 981 982 // only clear matching TTY_ID 983 if ( psched->context[ltid][CTX_TTY_ID] == channel ) 984 { 985 psched->context[ltid][CTX_TTY_ID] = -1; 986 } 987 } 988 989 // release TTY channel 990 _tty_channel[channel] = 0; 991 992 return 0; 993 } 994 995 ///////////////////////////////////////////////// 1558 unsigned int trdid = _get_thread_trdid(); 1559 _printf("\n[GIET_ERROR] in _sys_tty_release() : " 1560 "TTY channel already released for thread %x\n", trdid ); 1561 return -1111; 1562 } 1563 1564 // reset CTX_TTY_ID for the calling thread 1565 _set_context_slot( CTX_TTY_ID , 0xFFFFFFFF ); 1566 1567 // atomically decrement the _tty_channel_allocator[] array 1568 _atomic_increment( &_tty_channel_alloc[channel] , -1 ); 1569 1570 // release WTI mailbox if TTY channel no more used 1571 if ( USE_PIC && (_tty_channel_alloc[channel] == 0) ) 1572 { 1573 _ext_irq_release( ISR_TTY_RX , channel ); 1574 } 1575 1576 return GIET_SYSCALL_OK; 1577 } // end sys_tty_release() 1578 1579 //////////////////////////////////////// 996 1580 int _sys_tty_write( const char* buffer, 997 1581 unsigned int length, // number of characters … … 1002 1586 // compute and check tty channel 1003 1587 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 1004 if( channel >= NB_TTY_CHANNELS ) return -1 ;1588 if( channel >= NB_TTY_CHANNELS ) return -1111; 1005 1589 1006 1590 // write string to TTY channel … … 1021 1605 } 1022 1606 1023 /////////////////////////////////////// /////////1607 /////////////////////////////////////// 1024 1608 int _sys_tty_read( char* buffer, 1025 1609 unsigned int length, // unused … … 1028 1612 // compute and check tty channel 1029 1613 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 1030 if( channel >= NB_TTY_CHANNELS ) return -1; 1031 1032 // read one character from TTY channel 1033 if (_tty_rx_full[channel] == 0) 1034 { 1035 return 0; 1036 } 1037 else 1038 { 1039 *buffer = _tty_rx_buf[channel]; 1040 _tty_rx_full[channel] = 0; 1041 return 1; 1042 } 1614 if( channel >= NB_TTY_CHANNELS ) return -1111; 1615 1616 unsigned int save_sr; 1617 unsigned int found = 0; 1618 1619 // get pointer on TTY_RX FIFO 1620 tty_fifo_t* fifo = &_tty_rx_fifo[channel]; 1621 1622 // try to read one character from FIFO 1623 // blocked in while loop until success 1624 while ( found == 0 ) 1625 { 1626 if ( fifo->sts == 0) // FIFO empty => deschedule 1627 { 1628 // enters critical section 1629 _it_disable( &save_sr ); 1630 1631 // set NORUN_MASK_TTY bit for calling thread 1632 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 1633 unsigned int ltid = psched->current; 1634 _atomic_or( &psched->context[ltid].slot[CTX_NORUN_ID] , NORUN_MASK_TTY ); 1635 1636 // register descheduling thread trdid 1637 fifo->trdid = _get_thread_trdid(); 1638 1639 // deschedule calling thread 1640 _ctx_switch(); 1641 1642 // exit critical section 1643 _it_restore( &save_sr ); 1644 } 1645 else // FIFO not empty => get one character 1646 { 1647 *buffer = fifo->data[fifo->ptr]; 1648 fifo->sts = fifo->sts - 1; 1649 fifo->ptr = (fifo->ptr + 1) % TTY_FIFO_DEPTH; 1650 found = 1; 1651 } 1652 } 1653 1654 return 1; 1043 1655 } 1044 1656 1045 /////////////////////////////////////////// 1046 int _sys_tty_get_lock( unsigned int channel, // unused 1047 unsigned int * save_sr_ptr ) 1048 { 1049 // check tty channel 1050 if( channel != 0 ) return 1; 1051 1052 _it_disable( save_sr_ptr ); 1053 _sqt_lock_acquire( &_tty0_sqt_lock ); 1054 return 0; 1055 } 1056 1057 /////////////////////////////////////////////// 1058 int _sys_tty_release_lock( unsigned int channel, 1059 unsigned int * save_sr_ptr ) 1060 { 1061 // check tty channel 1062 if( channel != 0 ) return 1; 1063 1064 _sqt_lock_release( &_tty0_sqt_lock ); 1065 _it_restore( save_sr_ptr ); 1066 return 0; 1067 } 1657 1068 1658 1069 1659 ////////////////////////////////////////////////////////////////////////////// 1070 // TIM related syscall handlers1660 // TIMER related syscall handlers 1071 1661 ////////////////////////////////////////////////////////////////////////////// 1072 1662 … … 1074 1664 int _sys_tim_alloc() 1075 1665 { 1076 // get a new timer index 1077 unsigned int channel = _atomic_increment( &_tim_channel_allocator, 1 ); 1078 1666 1667 #if NB_TIM_CHANNELS 1668 1669 unsigned int channel; // allocated TIMER channel 1670 1671 unsigned int trdid = _get_thread_trdid(); 1672 1673 // check no TIMER already allocated to calling thread 1674 if ( _get_context_slot( CTX_TIM_ID ) < NB_TIM_CHANNELS ) 1675 { 1676 _printf("\n[GIET_ERROR] in _sys_tim_alloc() : " 1677 "TIMER channel already allocated to thread %x\n", trdid ); 1678 return -1111; 1679 } 1680 1681 // get a TIMER channel 1682 for ( channel = 0 ; channel < NB_TIM_CHANNELS ; channel++ ) 1683 { 1684 unsigned int* palloc = &_tim_channel_alloc[channel]; 1685 1686 if ( _atomic_test_and_set( palloc , 1 ) == 0 ) break; 1687 } 1079 1688 if ( channel >= NB_TIM_CHANNELS ) 1080 1689 { 1081 _printf("\n[GIET_ERROR] in _sys_tim_alloc() : not enough TIM channels\n"); 1082 return -1; 1083 } 1084 else 1085 { 1086 _set_context_slot( CTX_TIM_ID, channel ); 1087 return 0; 1088 } 1089 } 1090 1091 //////////////////// 1092 // NOTE: not a syscall 1093 int _sys_tim_release() 1094 { 1095 // release one timer 1096 _atomic_increment( &_tim_channel_allocator, 0xFFFFFFFF ); 1097 1098 return 0; 1099 } 1690 _printf("\n[GIET_ERROR] in _sys_tim_alloc() : " 1691 "no TIMER channel available for thread %x\n", trdid ); 1692 return -1111; 1693 } 1694 1695 // allocate a WTI mailbox to the calling proc if external IRQ 1696 unsigned int wti_id; 1697 if ( USE_PIC ) _ext_irq_alloc( ISR_TIMER , channel , &wti_id ); 1698 1699 // register wti_id and coordinates for processor receiving WTI 1700 unsigned int procid = _get_procid(); 1701 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 1702 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 1703 unsigned int p = procid & ((1<<P_WIDTH)-1); 1704 _tim_channel_wti[channel] = x<<24 | y<<16 | p<<8 | wti_id; 1705 1706 // update CTX_TIM_ID in thread context 1707 _set_context_slot( CTX_TIM_ID, channel ); 1708 1709 return GIET_SYSCALL_OK; 1710 1711 #else 1712 1713 _printf("\n[GIET ERROR] in _sys_tim_alloc() : NB_TIM_CHANNELS = 0\n"); 1714 return -1111; 1715 1716 #endif 1717 } // end _sys_tim_alloc() 1718 1719 1720 ////////////////////// 1721 int _sys_tim_release() // NOTE: not a syscall 1722 { 1723 1724 #if NB_TIM_CHANNELS 1725 1726 unsigned int channel = _get_context_slot( CTX_TIM_ID ); 1727 1728 if ( channel == -1 ) 1729 { 1730 unsigned int trdid = _get_thread_trdid(); 1731 _printf("\n[GIET_ERROR] in _sys_tim_release() : " 1732 "TIMER channel already released for thread %x\n", trdid ); 1733 return -1111; 1734 } 1735 1736 // reset CTX_TIM_ID for the calling thread 1737 _set_context_slot( CTX_TIM_ID , 0xFFFFFFFF ); 1738 1739 // reset the _tim_channel_alloc[] array 1740 _tim_channel_alloc[channel] = 0; 1741 1742 // release WTI mailbox if TTY channel no more used 1743 if ( USE_PIC ) 1744 { 1745 _ext_irq_release( PERIPH_TYPE_TIM , channel ); 1746 } 1747 1748 return GIET_SYSCALL_OK; 1749 1750 #else 1751 1752 _printf("\n[GIET ERROR] in _sys_tim_release() : NB_TIM_CHANNELS = 0\n"); 1753 return -1111; 1754 1755 #endif 1756 } // end _sys_tim_release() 1100 1757 1101 1758 ///////////////////////////////////////// 1102 1759 int _sys_tim_start( unsigned int period ) 1103 1760 { 1761 1762 #if NB_TIM_CHANNELS 1763 1104 1764 // get timer index 1105 1765 unsigned int channel = _get_context_slot( CTX_TIM_ID ); … … 1107 1767 { 1108 1768 _printf("\n[GIET_ERROR] in _sys_tim_start() : not enough TIM channels\n"); 1109 return -1 ;1769 return -1111; 1110 1770 } 1111 1771 … … 1113 1773 _timer_start( channel, period ); 1114 1774 1115 return 0; 1775 return GIET_SYSCALL_OK; 1776 1777 #else 1778 1779 _printf("\n[GIET ERROR] in _sys_tim_start() : NB_TIM_CHANNELS = 0\n"); 1780 return -1111; 1781 1782 #endif 1116 1783 } 1117 1784 … … 1119 1786 int _sys_tim_stop() 1120 1787 { 1788 1789 #if NB_TIM_CHANNELS 1790 1121 1791 // get timer index 1122 1792 unsigned int channel = _get_context_slot( CTX_TIM_ID ); … … 1124 1794 { 1125 1795 _printf("\n[GIET_ERROR] in _sys_tim_stop() : illegal timer index\n"); 1126 return -1 ;1796 return -1111; 1127 1797 } 1128 1798 … … 1130 1800 _timer_stop( channel ); 1131 1801 1132 return 0; 1802 return GIET_SYSCALL_OK; 1803 1804 #else 1805 1806 _printf("\n[GIET ERROR] in _sys_tim_stop() : NB_TIM_CHANNELS = 0\n"); 1807 return -1111; 1808 1809 #endif 1133 1810 } 1811 1134 1812 1135 1813 ////////////////////////////////////////////////////////////////////////////// … … 1138 1816 1139 1817 #define NIC_CONTAINER_SIZE 4096 1818 1819 #if NB_NIC_CHANNELS 1140 1820 1141 1821 //////////////////////////////////////// … … 1144 1824 unsigned int ymax ) 1145 1825 { 1826 mapping_header_t *header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 1827 mapping_vspace_t *vspace = _get_vspace_base(header); 1828 mapping_thread_t *thread = _get_thread_base(header); 1829 1830 // get calling thread trdid, vspace index, and number of threads 1831 unsigned int trdid = _get_thread_trdid(); 1832 unsigned int vsid = _get_context_slot( CTX_VSID_ID ); 1833 unsigned int users = vspace[vsid].threads; 1834 1146 1835 // check xmax / ymax parameters 1147 if ( xmax > X_SIZE ) 1148 { 1149 _printf("\n[GIET_ERROR] in _sys_nic_alloc() xmax argument too large\n"); 1150 return -1; 1151 } 1152 if ( ymax > Y_SIZE ) 1153 { 1154 _printf("\n[GIET_ERROR] in _sys_nic_alloc() ymax argument too large\n"); 1155 return -1; 1836 if ( (xmax > X_SIZE) || (ymax > Y_SIZE) ) 1837 { 1838 _printf("\n[GIET_ERROR] in _sys_nic_alloc() " 1839 "xmax or ymax argument too large for thread %x\n", trdid ); 1840 return -1111; 1156 1841 } 1157 1842 … … 1160 1845 //////////////////////////////////////////////////////// 1161 1846 1162 // get a NIC_RX or NIC_TX channel index 1163 unsigned int nic_channel; 1164 unsigned int cma_channel; 1165 1166 if ( is_rx ) nic_channel = _atomic_increment( &_nic_rx_channel_allocator, 1 ); 1167 else nic_channel = _atomic_increment( &_nic_tx_channel_allocator, 1 ); 1168 1847 unsigned int nic_channel; 1848 unsigned int cma_channel; 1849 unsigned int* palloc; 1850 1851 // get a NIC_RX or NIC_TX channel 1852 for ( nic_channel = 0 ; nic_channel < NB_NIC_CHANNELS ; nic_channel++ ) 1853 { 1854 if ( is_rx ) palloc = &_nic_rx_channel_alloc[nic_channel]; 1855 else palloc = &_nic_tx_channel_alloc[nic_channel]; 1856 1857 if ( _atomic_test_and_set( palloc , users ) == 0 ) break; 1858 } 1169 1859 if ( (nic_channel >= NB_NIC_CHANNELS) ) 1170 1860 { 1171 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n"); 1172 return -1; 1173 } 1174 1175 // get a CMA channel index 1861 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : " 1862 "no NIC channel available for thread %x\n", trdid ); 1863 return -1111; 1864 } 1865 1866 // get a CMA channel 1176 1867 for ( cma_channel = 0 ; cma_channel < NB_CMA_CHANNELS ; cma_channel++ ) 1177 1868 { 1178 if ( !_cma_channel[cma_channel] ) 1869 palloc = &_cma_channel_alloc[cma_channel]; 1870 1871 if ( _atomic_test_and_set( palloc , users ) == 0 ) break; 1872 } 1873 if ( cma_channel >= NB_CMA_CHANNELS ) 1874 { 1875 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : " 1876 "no CMA channel available for thread %x\n", trdid ); 1877 if ( is_rx ) _nic_rx_channel_alloc[nic_channel] = 0; 1878 else _nic_tx_channel_alloc[nic_channel] = 0; 1879 return -1111; 1880 } 1881 1882 #if GIET_DEBUG_NIC 1883 _printf("\n[GIET DEBUG NIC] Thread %d enters sys_nic_alloc() at cycle %d\n" 1884 " nic_channel = %d / cma_channel = %d\n", 1885 trdid , _get_proctime() , nic_channel , cma_channel ); 1886 #endif 1887 1888 // register nic_index and cma_index in all threads 1889 // contexts that are in the same vspace 1890 unsigned int tid; 1891 for (tid = vspace[vsid].thread_offset; 1892 tid < (vspace[vsid].thread_offset + vspace[vsid].threads); 1893 tid++) 1894 { 1895 unsigned int y_size = header->y_size; 1896 unsigned int cid = thread[tid].clusterid; 1897 unsigned int x = cid / y_size; 1898 unsigned int y = cid % y_size; 1899 unsigned int p = thread[tid].proclocid; 1900 unsigned int ltid = thread[tid].ltid; 1901 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 1902 1903 if ( is_rx ) 1179 1904 { 1180 _cma_channel[cma_channel] = 1; 1181 break; 1905 if ( (psched->context[ltid].slot[CTX_NIC_RX_ID] < NB_NIC_CHANNELS) || 1906 (psched->context[ltid].slot[CTX_CMA_RX_ID] < NB_CMA_CHANNELS) ) 1907 { 1908 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : " 1909 "NIC_RX or CMA_RX channel already allocated for thread %x\n", trdid ); 1910 _nic_rx_channel_alloc[nic_channel] = 0; 1911 _cma_channel_alloc[cma_channel] = 0; 1912 return -1111; 1913 } 1914 else 1915 { 1916 psched->context[ltid].slot[CTX_NIC_RX_ID] = nic_channel; 1917 psched->context[ltid].slot[CTX_CMA_RX_ID] = cma_channel; 1918 } 1182 1919 } 1183 } 1184 1185 if ( cma_channel >= NB_CMA_CHANNELS ) 1186 { 1187 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n"); 1188 return -1; 1189 } 1190 1191 #if GIET_DEBUG_NIC 1192 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 1193 _printf("\n[GIET DEBUG NIC] Task %d enters sys_nic_alloc() at cycle %d\n" 1194 " nic_channel = %d / cma_channel = %d\n", 1195 thread , _get_proctime() , nic_channel , cma_channel ); 1196 #endif 1197 1198 // register nic_index and cma_index in task context 1199 if ( is_rx ) 1200 { 1201 _set_context_slot( CTX_NIC_RX_ID, nic_channel ); 1202 _set_context_slot( CTX_CMA_RX_ID, cma_channel ); 1203 } 1204 else 1205 { 1206 _set_context_slot( CTX_NIC_TX_ID, nic_channel ); 1207 _set_context_slot( CTX_CMA_TX_ID, cma_channel ); 1208 } 1920 else // is_tx 1921 { 1922 if ( (psched->context[ltid].slot[CTX_NIC_TX_ID] < NB_NIC_CHANNELS) || 1923 (psched->context[ltid].slot[CTX_CMA_TX_ID] < NB_CMA_CHANNELS) ) 1924 { 1925 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : " 1926 "NIC_TX or CMA_TX channel already allocated for thread %x\n", trdid ); 1927 _nic_tx_channel_alloc[nic_channel] = 0; 1928 _cma_channel_alloc[cma_channel] = 0; 1929 return -1111; 1930 } 1931 else 1932 { 1933 psched->context[ltid].slot[CTX_NIC_TX_ID] = nic_channel; 1934 psched->context[ltid].slot[CTX_CMA_TX_ID] = cma_channel; 1935 } 1936 } 1937 } // end loop on threads 1209 1938 1210 1939 ///////////////////////////////////////////////////////////////////////////////// … … 1241 1970 if ( vaddr == 0 ) // not enough kernel heap memory in cluster[cx,cy] 1242 1971 { 1243 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap"1244 " in cluster[%d,%d]\n", cx, cy );1245 return -1 ;1972 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : " 1973 "not enough kenel heap in cluster[%d,%d]\n", cx, cy ); 1974 return -1111; 1246 1975 } 1247 1976 … … 1252 1981 if ( cont_paddr & 0x3F ) 1253 1982 { 1254 _printf("\n[GIET ERROR] in _sys_nic_alloc() : container address of cluster[%d,%d] not aligned\n",1255 cx, cy);1256 return -1 ;1983 _printf("\n[GIET ERROR] in _sys_nic_alloc() : " 1984 "container address of cluster[%d,%d] not aligned\n", cx, cy); 1985 return -1111; 1257 1986 } 1258 1987 … … 1270 1999 if ( vaddr == 0 ) // not enough kernel heap memory in cluster[cx,cy] 1271 2000 { 1272 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap"1273 " in cluster[%d,%d]\n", cx, cy );1274 return -1 ;2001 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : " 2002 "not enough kernel heap in cluster[%d,%d]\n", cx, cy ); 2003 return -1111; 1275 2004 } 1276 2005 … … 1281 2010 if ( sts_paddr & 0x3F ) 1282 2011 { 1283 _printf("\n[GIET ERROR] in _sys_nic_alloc() : status address of cluster[%d,%d] not aligned\n",1284 cx, cy);1285 return -1 ;2012 _printf("\n[GIET ERROR] in _sys_nic_alloc() : " 2013 "status address of cluster[%d,%d] not aligned\n", cx, cy); 2014 return -1111; 1286 2015 } 1287 2016 … … 1385 2114 #endif 1386 2115 1387 return nic_channel;2116 return GIET_SYSCALL_OK; 1388 2117 } // end _sys_nic_alloc() 1389 2118 1390 2119 1391 //////////////////////////////////////// 1392 // NOTE: not a syscall 1393 int _sys_nic_release( unsigned int is_rx ) 1394 { 1395 if ( is_rx ) 1396 _atomic_increment( &_nic_rx_channel_allocator , 0xFFFFFFFF ); 1397 else 1398 _atomic_increment( &_nic_tx_channel_allocator , 0xFFFFFFFF ); 1399 1400 return 0; 1401 } 1402 1403 1404 //////////////////////////////////////// 1405 int _sys_nic_start( unsigned int is_rx, 1406 unsigned int channel ) 1407 { 2120 ////////////////////////////////////////// 2121 int _sys_nic_release( unsigned int is_rx ) // NOTE: not a syscall 2122 { 2123 unsigned int trdid = _get_thread_trdid(); 2124 1408 2125 unsigned int nic_channel; 1409 2126 unsigned int cma_channel; 1410 1411 // get NIC channel index and CMA channel index from task context2127 2128 // update the kernel tables 1412 2129 if ( is_rx ) 1413 2130 { 1414 2131 nic_channel = _get_context_slot( CTX_NIC_RX_ID ); 1415 2132 cma_channel = _get_context_slot( CTX_CMA_RX_ID ); 1416 } 2133 2134 if ( (nic_channel >= NB_NIC_CHANNELS) ) 2135 { 2136 _printf("\n[GIET ERROR] in _sys_nic_release() : " 2137 "NIC_RX channel already released for thread %x\n", trdid ); 2138 return -1111; 2139 } 2140 if ( (cma_channel >= NB_CMA_CHANNELS) ) 2141 { 2142 _printf("\n[GIET ERROR] in _sys_nic_release() : " 2143 "CMA_RX channel already released for thread %x\n", trdid ); 2144 return -1111; 2145 } 2146 2147 // atomically decrement the NIC and CMA channel allocators 2148 _atomic_increment( &_nic_rx_channel_alloc[nic_channel] , -1 ); 2149 _atomic_increment( &_cma_channel_alloc[cma_channel] , -1 ); 2150 2151 // stop the NIC and CMA peripherals channels if no more users 2152 if ( (_nic_rx_channel_alloc[nic_channel] == 0) && 2153 (_cma_channel_alloc[cma_channel] == 0) ) _sys_nic_stop( 1 ); 2154 2155 // reset the calling thread context slots 2156 _set_context_slot( CTX_NIC_RX_ID , 0xFFFFFFFF ); 2157 _set_context_slot( CTX_CMA_RX_ID , 0xFFFFFFFF ); 2158 } 1417 2159 else 1418 2160 { 1419 2161 nic_channel = _get_context_slot( CTX_NIC_TX_ID ); 1420 2162 cma_channel = _get_context_slot( CTX_CMA_TX_ID ); 2163 2164 if ( (nic_channel >= NB_NIC_CHANNELS) ) 2165 { 2166 _printf("\n[GIET ERROR] in _sys_nic_release() : " 2167 "NIC_TX channel already released for thread %x\n", trdid ); 2168 return -1111; 2169 } 2170 if ( (cma_channel >= NB_CMA_CHANNELS) ) 2171 { 2172 _printf("\n[GIET ERROR] in _sys_nic_release() : " 2173 "CMA_TX channel already released for thread %x\n", trdid ); 2174 return -1111; 2175 } 2176 2177 // atomically decrement the NIC and CMA channel allocators 2178 _atomic_increment( &_nic_tx_channel_alloc[nic_channel] , -1 ); 2179 _atomic_increment( &_cma_channel_alloc[cma_channel] , -1 ); 2180 2181 // stop the NIC and CMA peripherals channels if no more users 2182 if ( (_nic_tx_channel_alloc[nic_channel] == 0) && 2183 (_cma_channel_alloc[cma_channel] == 0) ) _sys_nic_stop( 0 ); 2184 2185 // reset the calling thread context slots 2186 _set_context_slot( CTX_NIC_TX_ID , 0xFFFFFFFF ); 2187 _set_context_slot( CTX_CMA_TX_ID , 0xFFFFFFFF ); 2188 } 2189 2190 return GIET_SYSCALL_OK; 2191 } // end sys_nic_release() 2192 2193 2194 //////////////////////////////////////// 2195 int _sys_nic_start( unsigned int is_rx ) 2196 { 2197 unsigned int trdid = _get_context_slot( CTX_TRDID_ID ); 2198 2199 unsigned int nic_channel; 2200 unsigned int cma_channel; 2201 2202 // get NIC channel index and CMA channel index from thread context 2203 if ( is_rx ) 2204 { 2205 nic_channel = _get_context_slot( CTX_NIC_RX_ID ); 2206 cma_channel = _get_context_slot( CTX_CMA_RX_ID ); 2207 } 2208 else 2209 { 2210 nic_channel = _get_context_slot( CTX_NIC_TX_ID ); 2211 cma_channel = _get_context_slot( CTX_CMA_TX_ID ); 1421 2212 } 1422 2213 1423 2214 #if GIET_DEBUG_NIC 1424 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 1425 _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start() at cycle %d\n" 2215 _printf("\n[GIET DEBUG NIC] Thread %x in _sys_nic_start() at cycle %d\n" 1426 2216 " get NIC channel = %d / CMA channel = %d\n", 1427 t hread, _get_proctime(), nic_channel, cma_channel );2217 trdid, _get_proctime(), nic_channel, cma_channel ); 1428 2218 #endif 1429 2219 1430 2220 // check NIC and CMA channels index 1431 if ( nic_channel != channel ) 1432 { 1433 _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal NIC channel\n"); 1434 return -1; 2221 if ( nic_channel >= NB_NIC_CHANNELS ) 2222 { 2223 _printf("\n[GIET_ERROR] in _sys_nic_start() : " 2224 "illegal NIC channel for thread %x\n", trdid ); 2225 return -1111; 1435 2226 } 1436 2227 if ( cma_channel >= NB_CMA_CHANNELS ) 1437 2228 { 1438 _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal CMA channel\n"); 1439 return -1; 2229 _printf("\n[GIET_ERROR] in _sys_nic_start() : " 2230 "illegal CMA channel for thread %x\n", trdid ); 2231 return -1111; 1440 2232 } 1441 2233 … … 1450 2242 #if GIET_DEBUG_NIC 1451 2243 _printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_start() at cycle %d\n", 1452 t hread , _get_proctime() );1453 #endif 1454 1455 return 0;2244 trdid , _get_proctime() ); 2245 #endif 2246 2247 return GIET_SYSCALL_OK; 1456 2248 } // end _sys_nic_start() 1457 2249 … … 1459 2251 ////////////////////////////////////// 1460 2252 int _sys_nic_move( unsigned int is_rx, 1461 unsigned int channel,1462 2253 void* buffer ) 1463 2254 { 2255 unsigned int trdid = _get_context_slot( CTX_TRDID_ID ); 2256 2257 unsigned int channel; 1464 2258 1465 2259 #if GIET_DEBUG_NIC 1466 unsigned int thread = _get_context_slot( CTX_TRDID_ID );1467 2260 _printf("\n[GIET DEBUG NIC] Task %d enters _sys_nic_move() at cycle %d\n", 1468 thread , _get_proctime() ); 1469 #endif 2261 trdid , _get_proctime() ); 2262 #endif 2263 2264 // get NIC channel index from thread context 2265 if ( is_rx ) channel = _get_context_slot( CTX_NIC_RX_ID ); 2266 else channel = _get_context_slot( CTX_NIC_TX_ID ); 1470 2267 1471 2268 // check NIC channel index 1472 2269 if ( channel >= NB_NIC_CHANNELS ) 1473 2270 { 1474 _printf("\n[GIET_ERROR] in _sys_nic_move() : illegal NIC channel index\n"); 1475 return -1; 2271 _printf("\n[GIET_ERROR] in _sys_nic_move() : " 2272 "illegal NIC channel index for thread %x\n", trdid ); 2273 return -1111; 1476 2274 } 1477 2275 … … 1485 2283 unsigned int ymax = ker_chbuf->ymax; 1486 2284 1487 // get cluster coordinates for the processor running the calling t ask2285 // get cluster coordinates for the processor running the calling thread 1488 2286 unsigned int procid = _get_procid(); 1489 2287 unsigned int cx = procid >> (Y_WIDTH + P_WIDTH); … … 1495 2293 _printf("\n[GIET_ERROR] in _sys_nic_move() : processor X coordinate = %d" 1496 2294 " / xmax = %d\n", cx , xmax ); 1497 return -1 ;2295 return -1111; 1498 2296 } 1499 2297 if ( cy >= ymax ) … … 1501 2299 _printf("\n[GIET_ERROR] in _sys_nic_move() : processor Y coordinate = %d" 1502 2300 " / ymax = %d\n", cy , ymax ); 1503 return -1 ;2301 return -1111; 1504 2302 } 1505 2303 … … 1518 2316 { 1519 2317 _printf("\n[GIET ERROR] in _sys_nic_tx_move() : illegal user buffer address\n"); 1520 return -1 ;2318 return -1111; 1521 2319 } 1522 2320 … … 1606 2404 #endif 1607 2405 1608 return 0;2406 return GIET_SYSCALL_OK; 1609 2407 } // end _sys_nic_move() 1610 2408 1611 2409 1612 //////////////////////////////////////// 1613 int _sys_nic_stop( unsigned int is_rx, 1614 unsigned int channel ) 1615 { 2410 /////////////////////////////////////// 2411 int _sys_nic_stop( unsigned int is_rx ) 2412 { 2413 unsigned int trdid = _get_context_slot( CTX_TRDID_ID ); 2414 1616 2415 unsigned int nic_channel; 1617 2416 unsigned int cma_channel; … … 1630 2429 1631 2430 // check NIC and CMA channels index 1632 if ( nic_channel != channel ) 1633 { 1634 _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal NIC channel\n"); 1635 return -1; 2431 if ( nic_channel >= NB_NIC_CHANNELS ) 2432 { 2433 _printf("\n[GIET_ERROR] in _sys_nic_stop() : " 2434 "illegal NIC channel for thread %x\n", trdid ); 2435 return -1111; 1636 2436 } 1637 2437 if ( cma_channel >= NB_CMA_CHANNELS ) 1638 2438 { 1639 _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal CMA channel\n"); 1640 return -1; 1641 } 2439 _printf("\n[GIET_ERROR] in _sys_nic_stop() : " 2440 "illegal CMA channel for thread %x\n", trdid ); 2441 return -1111; 2442 } 2443 2444 // desactivates the CMA channel 2445 _cma_set_register( cma_channel, CHBUF_RUN , 0 ); 2446 2447 // wait until CMA channel IDLE 2448 unsigned int volatile status; 2449 do 2450 { 2451 status = _cma_get_register( cma_channel, CHBUF_STATUS ); 2452 } while ( status ); 1642 2453 1643 2454 // desactivates the NIC channel 1644 2455 _nic_channel_stop( nic_channel, is_rx ); 1645 2456 1646 // desactivates the CMA channel 1647 _cma_set_register( cma_channel, CHBUF_RUN , 0 ); 1648 1649 return 0; 2457 return GIET_SYSCALL_OK; 1650 2458 } // end _sys_nic_stop() 1651 2459 1652 2460 //////////////////////////////////////// 1653 int _sys_nic_clear( unsigned int is_rx, 1654 unsigned int channel ) 1655 { 1656 unsigned int nic_channel; 2461 int _sys_nic_clear( unsigned int is_rx ) 2462 { 2463 unsigned int trdid = _get_context_slot( CTX_TRDID_ID ); 2464 2465 unsigned int channel; 1657 2466 1658 2467 // get NIC channel 1659 if ( is_rx ) nic_channel = _get_context_slot( CTX_NIC_RX_ID ); 1660 else nic_channel = _get_context_slot( CTX_NIC_TX_ID ); 1661 1662 if ( nic_channel != channel ) 1663 { 1664 _printf("\n[GIET_ERROR] in _sys_nic_clear(): illegal NIC channel\n"); 1665 return -1; 2468 if ( is_rx ) channel = _get_context_slot( CTX_NIC_RX_ID ); 2469 else channel = _get_context_slot( CTX_NIC_TX_ID ); 2470 2471 if ( channel >= NB_NIC_CHANNELS ) 2472 { 2473 _printf("\n[GIET_ERROR] in _sys_nic_clear() : " 2474 "illegal NIC channel for thread %x\n", trdid ); 2475 return -1111; 1666 2476 } 1667 2477 … … 1688 2498 _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_BROADCAST , 0 ); 1689 2499 } 1690 return 0;2500 return GIET_SYSCALL_OK; 1691 2501 } // en _sys_nic_clear() 1692 2502 1693 2503 //////////////////////////////////////// 1694 int _sys_nic_stats( unsigned int is_rx, 1695 unsigned int channel ) 1696 { 2504 int _sys_nic_stats( unsigned int is_rx ) 2505 { 2506 unsigned int trdid = _get_context_slot( CTX_TRDID_ID ); 2507 1697 2508 unsigned int nic_channel; 1698 2509 … … 1701 2512 else nic_channel = _get_context_slot( CTX_NIC_TX_ID ); 1702 2513 1703 if ( nic_channel != channel ) 1704 { 1705 _printf("\n[GIET_ERROR] in _sys_nic_stats(): illegal NIC channel\n"); 1706 return -1; 2514 if ( nic_channel >= NB_NIC_CHANNELS ) 2515 { 2516 _printf("\n[GIET_ERROR] in _sys_nic_stats() : " 2517 "illegal NIC channel for thread %x\n", trdid ); 2518 return -1111; 1707 2519 } 1708 2520 … … 1759 2571 broadcast ); 1760 2572 } 1761 return 0;2573 return GIET_SYSCALL_OK; 1762 2574 } // end _sys_nic_stats() 2575 2576 #endif 1763 2577 1764 2578 ///////////////////////////////////////////////////////////////////////////////////////// … … 1774 2588 memcpy( fbf_address, buffer, length); 1775 2589 1776 return 0;2590 return GIET_SYSCALL_OK; 1777 2591 } 1778 2592 … … 1785 2599 memcpy( buffer, fbf_address, length); 1786 2600 1787 return 0;2601 return GIET_SYSCALL_OK; 1788 2602 } 1789 2603 … … 1791 2605 int _sys_fbf_cma_alloc() 1792 2606 { 2607 unsigned int trdid = _get_thread_trdid(); 2608 1793 2609 if ( _get_context_slot( CTX_CMA_FB_ID ) < NB_CMA_CHANNELS ) 1794 2610 { 1795 _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : CMA channel already allocated\n"); 1796 return 0; 1797 } 1798 1799 // get a new CMA channel index 2611 _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : " 2612 "CMA channel already allocated for thread %x\n", trdid ); 2613 return GIET_SYSCALL_OK; 2614 } 2615 2616 // get a CMA channel 1800 2617 unsigned int channel; 1801 1802 2618 for ( channel = 0 ; channel < NB_CMA_CHANNELS ; channel++ ) 1803 2619 { 1804 if ( !_cma_channel[channel] ) 1805 { 1806 _cma_channel[channel] = 1; 1807 break; 1808 } 1809 } 1810 2620 unsigned int* palloc = &_cma_channel_alloc[channel]; 2621 if ( _atomic_test_and_set( palloc , 1 ) == 0 ) break; 2622 } 1811 2623 if ( channel >= NB_CMA_CHANNELS ) 1812 2624 { 1813 2625 _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : no CMA channel available\n"); 1814 return -1 ;2626 return -1111; 1815 2627 } 1816 2628 else 1817 2629 { 1818 2630 _set_context_slot( CTX_CMA_FB_ID, channel ); 1819 return 0;2631 return GIET_SYSCALL_OK; 1820 2632 } 1821 2633 } // end sys_fbf_cma_alloc() 1822 2634 1823 //////////////////////// 1824 // NOTE: not a syscall 1825 int _sys_fbf_cma_release() 2635 ////////////////////////// 2636 int _sys_fbf_cma_release() // Not a syscall 1826 2637 { 1827 2638 unsigned int channel = _get_context_slot( CTX_CMA_FB_ID ); 2639 unsigned int trdid = _get_thread_trdid(); 1828 2640 1829 2641 if ( channel >= NB_CMA_CHANNELS ) 1830 2642 { 1831 _printf("\n[GIET_ERROR] in _sys_fbf_cma_release() : CMA channel already released\n"); 1832 return -1; 1833 } 1834 1835 // stop fb 2643 _printf("\n[GIET_ERROR] in _sys_fbf_cma_release() : " 2644 "CMA_FB channel already releasedifor thread %x\n", trdid ); 2645 return -1111; 2646 } 2647 2648 // stop CMA transfer 1836 2649 _sys_fbf_cma_stop(); 1837 2650 1838 // reset CTX_CMA_FB_ID for t ask1839 _set_context_slot( CTX_CMA_FB_ID, -1);2651 // reset CTX_CMA_FB_ID for thread 2652 _set_context_slot( CTX_CMA_FB_ID, 0xFFFFFFFF ); 1840 2653 1841 2654 // release CMA channel 1842 _cma_channel [channel] = 0;1843 1844 return 0;2655 _cma_channel_alloc[channel] = 0; 2656 2657 return GIET_SYSCALL_OK; 1845 2658 } 1846 2659 … … 1868 2681 { 1869 2682 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : CMA channel index too large\n"); 1870 return -1 ;2683 return -1111; 1871 2684 } 1872 2685 … … 1890 2703 { 1891 2704 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : user buffer not aligned\n"); 1892 return -1 ;2705 return -1111; 1893 2706 } 1894 2707 … … 1898 2711 { 1899 2712 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : user status not aligned\n"); 1900 return -1 ;2713 return -1111; 1901 2714 } 1902 2715 … … 1917 2730 { 1918 2731 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : buf0 not in user space\n"); 1919 return -1 ;2732 return -1111; 1920 2733 } 1921 2734 … … 1925 2738 { 1926 2739 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : sts0 not in user space\n"); 1927 return -1 ;2740 return -1111; 1928 2741 } 1929 2742 … … 1938 2751 { 1939 2752 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : buf1 not in user space\n"); 1940 return -1 ;2753 return -1111; 1941 2754 } 1942 2755 … … 1946 2759 { 1947 2760 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : sts1 not in user space\n"); 1948 return -1 ;2761 return -1111; 1949 2762 } 1950 2763 … … 1974 2787 #endif 1975 2788 1976 return 0;2789 return GIET_SYSCALL_OK; 1977 2790 1978 2791 #else 1979 2792 1980 2793 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : NB_CMA_CHANNELS = 0\n"); 1981 return -1 ;2794 return -1111; 1982 2795 1983 2796 #endif … … 1995 2808 { 1996 2809 _printf("\n[GIET ERROR] in _fbf_cma_start() : CMA channel index too large\n"); 1997 return -1 ;2810 return -1111; 1998 2811 } 1999 2812 … … 2005 2818 _printf("\n[GIET ERROR] in _sys_fbf_cma_start() :\n" 2006 2819 "Buffer initialization has not been done\n"); 2007 return -1 ;2820 return -1111; 2008 2821 } 2009 2822 … … 2034 2847 _cma_set_register( channel, CHBUF_RUN , 1 ); 2035 2848 2036 return 0;2849 return GIET_SYSCALL_OK; 2037 2850 2038 2851 #else 2039 2852 2040 2853 _printf("\n[GIET ERROR] in _sys_fbf_cma_start() : NB_CMA_CHANNELS = 0\n"); 2041 return -1 ;2854 return -1111; 2042 2855 2043 2856 #endif … … 2058 2871 _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : " 2059 2872 "CMA channel index too large\n"); 2060 return -1 ;2873 return -1111; 2061 2874 } 2062 2875 … … 2138 2951 _mmc_sync( fbf_sts_paddr, 4 ); 2139 2952 2140 return 0;2953 return GIET_SYSCALL_OK; 2141 2954 2142 2955 #else 2143 2956 2144 2957 _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : no CMA channel allocated\n"); 2145 return -1 ;2958 return -1111; 2146 2959 2147 2960 #endif … … 2159 2972 { 2160 2973 _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : CMA channel index too large\n"); 2161 return -1 ;2974 return -1111; 2162 2975 } 2163 2976 … … 2165 2978 _cma_set_register( channel, CHBUF_RUN, 0 ); 2166 2979 2167 return 0;2980 return GIET_SYSCALL_OK; 2168 2981 2169 2982 #else 2170 2983 2171 2984 _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : no CMA channel allocated\n"); 2172 return -1 ;2985 return -1111; 2173 2986 2174 2987 #endif … … 2184 2997 { 2185 2998 _printf("\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() ); 2186 return -1;2999 return GIET_SYSCALL_UNDEFINED_SYSTEM_CALL; 2187 3000 } 2188 3001 … … 2198 3011 *p = gpid & ((1<<P_WIDTH)-1); 2199 3012 2200 return 0; 2201 } 2202 2203 ////////////////////////////////// 2204 int _sys_task_exit( char* string ) 2205 { 2206 unsigned int date = _get_proctime(); 2207 2208 unsigned int gpid = _get_procid(); 2209 unsigned int cluster_xy = gpid >> P_WIDTH; 2210 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 2211 unsigned int x = cluster_xy >> Y_WIDTH; 2212 unsigned int p = gpid & ((1<<P_WIDTH)-1); 2213 2214 unsigned int ltid = _get_context_slot(CTX_LTID_ID); 2215 2216 // print exit message 2217 _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d" 2218 "\n Cause : %s\n\n", 2219 ltid, x, y, p, date, string ); 2220 2221 // set NORUN_MASK_TASK bit (non runnable state) 2222 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 2223 unsigned int* ptr = &psched->context[ltid][CTX_NORUN_ID]; 2224 _atomic_or( ptr , NORUN_MASK_TASK ); 2225 2226 // deschedule 2227 _sys_context_switch(); 2228 2229 return 0; 2230 } 2231 2232 ///////////////////////// 2233 int _sys_context_switch() 2234 { 2235 unsigned int save_sr; 2236 2237 _it_disable( &save_sr ); 2238 _ctx_switch(); 2239 _it_restore( &save_sr ); 2240 2241 return 0; 2242 } 2243 2244 //////////////////////// 2245 int _sys_local_task_id() 2246 { 2247 return _get_context_slot(CTX_LTID_ID); 2248 } 2249 2250 ///////////////////////// 2251 int _sys_global_task_id() 2252 { 2253 return _get_context_slot(CTX_GTID_ID); 2254 } 2255 2256 //////////////////// 2257 int _sys_thread_id() 2258 { 2259 return _get_context_slot(CTX_TRDID_ID); 3013 return GIET_SYSCALL_OK; 2260 3014 } 2261 3015 … … 2312 3066 *nprocs = 0; 2313 3067 } 2314 return 0;3068 return GIET_SYSCALL_OK; 2315 3069 } 2316 3070 … … 2340 3094 { 2341 3095 *vbase = vseg[vseg_id].vbase; 2342 return 0;3096 return GIET_SYSCALL_OK; 2343 3097 } 2344 3098 } 2345 3099 } 2346 3100 } 2347 return -1; // not found3101 return GIET_SYSCALL_VSEG_NOT_FOUND; 2348 3102 } 2349 3103 … … 2373 3127 { 2374 3128 *length = vseg[vseg_id].length; 2375 return 0;3129 return GIET_SYSCALL_OK; 2376 3130 } 2377 3131 } 2378 3132 } 2379 3133 } 2380 return -1; // not found3134 return GIET_SYSCALL_VSEG_NOT_FOUND; 2381 3135 } 2382 3136 … … 2392 3146 *y = (paddr>>32) & 0xF; 2393 3147 2394 return 0;3148 return GIET_SYSCALL_OK; 2395 3149 } 2396 3150 … … 2401 3155 unsigned int y ) 2402 3156 { 3157 // checking parameters 3158 if ( (x >= X_SIZE) || (y >= Y_SIZE) ) 3159 { 3160 *vaddr = 0; 3161 *length = 0; 3162 _printf("\n[GIET ERROR] in _sys_heap_info() : " 3163 "illegal (%d,%d) coordinates\n", x , y ); 3164 return GIET_SYSCALL_ILLEGAL_CLUSTER_COORDINATES; 3165 } 3166 2403 3167 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 2404 mapping_t ask_t * task = _get_task_base(header);3168 mapping_thread_t * thread = _get_thread_base(header); 2405 3169 mapping_vseg_t * vseg = _get_vseg_base(header); 2406 3170 mapping_vspace_t * vspace = _get_vspace_base(header); 2407 3171 2408 unsigned int t ask_id;3172 unsigned int thread_id; 2409 3173 unsigned int vspace_id; 2410 3174 unsigned int vseg_id = 0xFFFFFFFF; 2411 3175 2412 // searching the heap vseg 2413 if ( (x < X_SIZE) && (y < Y_SIZE) ) // searching a task in cluster(x,y) 2414 { 2415 // get vspace global index 2416 vspace_id = _get_context_slot(CTX_VSID_ID); 2417 2418 // scan all tasks in vspace 2419 unsigned int min = vspace[vspace_id].task_offset ; 2420 unsigned int max = min + vspace[vspace_id].tasks ; 2421 for ( task_id = min ; task_id < max ; task_id++ ) 3176 // get calling thread vspace index 3177 vspace_id = _get_context_slot(CTX_VSID_ID); 3178 3179 // scan all threads in vspace to find one in clyster[x,y] 3180 unsigned int min = vspace[vspace_id].thread_offset ; 3181 unsigned int max = min + vspace[vspace_id].threads ; 3182 for ( thread_id = min ; thread_id < max ; thread_id++ ) 3183 { 3184 if ( thread[thread_id].clusterid == (x * Y_SIZE + y) ) 2422 3185 { 2423 if ( task[task_id].clusterid == (x * Y_SIZE + y) ) 2424 { 2425 vseg_id = task[task_id].heap_vseg_id; 2426 if ( vseg_id != 0xFFFFFFFF ) break; 2427 } 3186 vseg_id = thread[thread_id].heap_vseg_id; 3187 break; 2428 3188 } 2429 }2430 else // searching in the calling task2431 {2432 task_id = _get_context_slot(CTX_GTID_ID);2433 vseg_id = task[task_id].heap_vseg_id;2434 3189 } 2435 3190 … … 2439 3194 *vaddr = vseg[vseg_id].vbase; 2440 3195 *length = vseg[vseg_id].length; 2441 return 0;2442 3196 } 2443 3197 else … … 2445 3199 *vaddr = 0; 2446 3200 *length = 0; 2447 return -1; 2448 } 3201 _printf("error in _sys_heap_info() : no heap in cluster (%d,%d)\n", x , y ); 3202 } 3203 return GIET_SYSCALL_OK; 2449 3204 } // end _sys_heap_info() 2450 2451 2452 ///////////////////////2453 int _sys_tasks_status()2454 {2455 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;2456 mapping_task_t * task = _get_task_base(header);2457 mapping_vspace_t * vspace = _get_vspace_base(header);2458 mapping_cluster_t * cluster = _get_cluster_base(header);2459 2460 unsigned int task_id;2461 unsigned int vspace_id;2462 2463 // scan all vspaces2464 for( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )2465 {2466 _printf("\n*** vspace %s\n", vspace[vspace_id].name );2467 2468 // scan all tasks in vspace2469 unsigned int min = vspace[vspace_id].task_offset ;2470 unsigned int max = min + vspace[vspace_id].tasks ;2471 for ( task_id = min ; task_id < max ; task_id++ )2472 {2473 unsigned int clusterid = task[task_id].clusterid;2474 unsigned int p = task[task_id].proclocid;2475 unsigned int x = cluster[clusterid].x;2476 unsigned int y = cluster[clusterid].y;2477 unsigned int ltid = task[task_id].ltid;2478 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p];2479 unsigned int norun = psched->context[ltid][CTX_NORUN_ID];2480 unsigned int current = psched->current;2481 2482 if ( current == ltid )2483 _printf(" - task %s on P[%d,%d,%d] : running\n", task[task_id].name, x, y, p );2484 else if ( norun == 0 )2485 _printf(" - task %s on P[%d,%d,%d] : runable\n", task[task_id].name, x, y, p );2486 else2487 _printf(" - task %s on P[%d,%d,%d] : blocked\n", task[task_id].name, x, y, p );2488 }2489 }2490 return 0;2491 } // end _sys_tasks_status()2492 2493 int _sys_fat_read( unsigned int fd_id,2494 unsigned int buffer,2495 unsigned int count )2496 {2497 return _fat_read(fd_id, buffer, count, 0);2498 }2499 2500 3205 2501 3206 -
soft/giet_vm/giet_kernel/sys_handler.h
r707 r709 16 16 #include "kernel_locks.h" 17 17 #include "stdio.h" 18 19 /////////////////////////////////////////////////////////////////////////////// 20 // Define the possible command values for the giet_pthread_control() syscall 21 /////////////////////////////////////////////////////////////////////////////// 22 23 #define THREAD_CMD_PAUSE 0 24 #define THREAD_CMD_RESUME 1 25 #define THREAD_CMD_CONTEXT 2 26 27 /////////////////////////////////////////////////////////////////////////////// 28 // Define the error codes for the thread related syscalls 29 /////////////////////////////////////////////////////////////////////////////// 30 31 #define GIET_SYSCALL_OK ( 0 ) 32 #define GIET_SYSCALL_VSPACE_NOT_FOUND (-1 ) 33 #define GIET_SYSCALL_THREAD_NOT_FOUND (-2 ) 34 #define GIET_SYSCALL_NOT_IN_SAME_VSPACE (-3 ) 35 #define GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT (-4 ) 36 #define GIET_SYSCALL_ILLEGAL_THREAD_COMMAND_TYPE (-5 ) 37 #define GIET_SYSCALL_CANNOT_LOAD_DATA_SEGMENT (-6 ) 38 #define GIET_SYSCALL_THREAD_ALREADY_ACTIVE (-7 ) 39 #define GIET_SYSCALL_MAIN_NOT_FOUND (-8 ) 40 #define GIET_SYSCALL_APPLI_CANNOT_BE_KILLED (-9 ) 41 #define GIET_SYSCALL_PTHREAD_ARGUMENT_NOT_SUPPORTED (-10) 42 #define GIET_SYSCALL_ILLEGAL_CLUSTER_COORDINATES (-11) 43 #define GIET_SYSCALL_VSEG_NOT_FOUND (-12) 44 #define GIET_SYSCALL_UNDEFINED_SYSTEM_CALL (-13) 45 #define GIET_SYSCALL_COPROCESSOR_NOT_FOUND (-14) 46 #define GIET_SYSCALL_COPROCESSOR_ILLEGAL_MODE (-15) 18 47 19 48 /////////////////////////////////////////////////////////////////////////////// … … 86 115 87 116 88 89 90 /////////////////////////////////////////////////////////////////////////////// 91 // Coprocessors related syscall handlers 92 /////////////////////////////////////////////////////////////////////////////// 93 94 int _sys_coproc_register_set( unsigned int cluster_xy, 95 unsigned int reg_index, 96 unsigned int value ); 97 98 int _sys_coproc_register_get( unsigned int cluster_xy, 99 unsigned int reg_index, 100 unsigned int* buffer ); 101 102 int _sys_coproc_alloc( unsigned int coproc_type, 103 unsigned int* coproc_info ); 104 105 int _sys_coproc_release( unsigned int coproc_reg_index ); 106 107 int _sys_coproc_channel_init( unsigned int channel, 108 giet_coproc_channel_t* desc ); 109 110 int _sys_coproc_run( unsigned int coproc_reg_index ); 111 112 int _sys_coproc_completed(); 117 ////////////////////////////////////////////////////////////////////////////// 118 // Applications related syscall handlers 119 ////////////////////////////////////////////////////////////////////////////// 120 121 extern int _sys_kill_application( char* name ); 122 123 extern int _sys_exec_application( char* name ); 124 125 extern int _sys_applications_status(); 126 127 ///////////////////////////////////////////////////////////////////////////// 128 // Threads related syscall handlers 129 ///////////////////////////////////////////////////////////////////////////// 130 131 extern int _sys_pthread_create( unsigned int* buffer, 132 void* attr, 133 void* function, 134 void* arg ); 135 136 extern int _sys_pthread_join( unsigned int trdid, 137 void* ptr ); 138 139 extern int _sys_pthread_kill( unsigned int trdid, 140 int signal ); 141 142 extern int _sys_pthread_exit( void* string); 143 144 extern int _sys_pthread_yield(); 145 146 extern int _sys_pthread_control( unsigned int command, 147 char* vspace_name, 148 char* thread_name ); 149 150 /////////////////////////////////////////////////////////////////////////////// 151 // Coprocessors related syscall handlers 152 /////////////////////////////////////////////////////////////////////////////// 153 154 extern int _sys_coproc_alloc( unsigned int coproc_type, 155 unsigned int* coproc_info ); 156 157 extern int _sys_coproc_release( unsigned int coproc_reg_index ); 158 159 extern int _sys_coproc_channel_init( unsigned int channel, 160 giet_coproc_channel_t* desc ); 161 162 extern int _sys_coproc_run( unsigned int coproc_reg_index ); 163 164 extern int _sys_coproc_completed(); 113 165 114 166 /////////////////////////////////////////////////////////////////////////////// … … 116 168 /////////////////////////////////////////////////////////////////////////////// 117 169 118 int _sys_tty_alloc( unsigned int shared );119 120 int _sys_tty_release();121 122 int _sys_tty_write( const char* buffer,170 extern int _sys_tty_alloc( unsigned int shared ); 171 172 extern int _sys_tty_release(); 173 174 extern int _sys_tty_write( const char* buffer, 123 175 unsigned int length, 124 176 unsigned int channel ); 125 177 126 int _sys_tty_read( char* buffer,178 extern int _sys_tty_read( char* buffer, 127 179 unsigned int length, 128 180 unsigned int channel ); … … 132 184 ////////////////////////////////////////////////////////////////////////////// 133 185 134 int _sys_tim_alloc();135 136 int _sys_tim_release();137 138 int _sys_tim_start( unsigned int period );139 140 int _sys_tim_stop();186 extern int _sys_tim_alloc(); 187 188 extern int _sys_tim_release(); 189 190 extern int _sys_tim_start( unsigned int period ); 191 192 extern int _sys_tim_stop(); 141 193 142 194 ////////////////////////////////////////////////////////////////////////////// … … 144 196 ////////////////////////////////////////////////////////////////////////////// 145 197 146 int _sys_nic_alloc( unsigned int is_rx, 147 unsigned int xmax, 148 unsigned int ymax ); 149 150 int _sys_nic_release( unsigned int is_rx ); 151 152 int _sys_nic_start( unsigned int is_rx, 153 unsigned int channel ); 154 155 int _sys_nic_move( unsigned int is_rx, 156 unsigned int channel, 157 void* buffer ); 158 159 int _sys_nic_stop( unsigned int is_rx, 160 unsigned int channel ); 161 162 int _sys_nic_clear( unsigned int is_rx, 163 unsigned int channel ); 164 165 int _sys_nic_stats( unsigned int is_rx, 166 unsigned int channel ); 198 extern int _sys_nic_alloc( unsigned int is_rx, 199 unsigned int xmax, 200 unsigned int ymax ); 201 202 extern int _sys_nic_release( unsigned int is_rx ); 203 204 extern int _sys_nic_start( unsigned int is_rx ); 205 206 extern int _sys_nic_move( unsigned int is_rx, 207 void* buffer ); 208 209 extern int _sys_nic_stop( unsigned int is_rx ); 210 211 extern int _sys_nic_clear( unsigned int is_rx ); 212 213 extern int _sys_nic_stats( unsigned int is_rx ); 167 214 168 215 ////////////////////////////////////////////////////////////////////////////// … … 170 217 ////////////////////////////////////////////////////////////////////////////// 171 218 172 int _sys_fbf_sync_write( unsigned int offset,219 extern int _sys_fbf_sync_write( unsigned int offset, 173 220 void* buffer, 174 221 unsigned int length ); 175 222 176 int _sys_fbf_sync_read( unsigned int offset,223 extern int _sys_fbf_sync_read( unsigned int offset, 177 224 void* buffer, 178 225 unsigned int length ); 179 226 180 int _sys_fbf_cma_alloc();181 182 int _sys_fbf_cma_release();183 184 int _sys_fbf_cma_init_buf(void* buf0_vbase,227 extern int _sys_fbf_cma_alloc(); 228 229 extern int _sys_fbf_cma_release(); 230 231 extern int _sys_fbf_cma_init_buf(void* buf0_vbase, 185 232 void* buf1_vbase, 186 233 void* sts0_vaddr, 187 234 void* sts1_vaddr ); 188 235 189 int _sys_fbf_cma_start( unsigned int length );190 191 int _sys_fbf_cma_display( unsigned int buffer_index );192 193 int _sys_fbf_cma_stop();236 extern int _sys_fbf_cma_start( unsigned int length ); 237 238 extern int _sys_fbf_cma_display( unsigned int buffer_index ); 239 240 extern int _sys_fbf_cma_stop(); 194 241 195 242 ////////////////////////////////////////////////////////////////////////////// … … 197 244 ////////////////////////////////////////////////////////////////////////////// 198 245 199 int _sys_ukn();200 201 int _sys_proc_xyp( unsigned int* x,246 extern int _sys_ukn(); 247 248 extern int _sys_proc_xyp( unsigned int* x, 202 249 unsigned int* y, 203 250 unsigned int* p ); 204 251 205 int _sys_task_exit( char* string ); 206 207 int _sys_kill_application( char* name ); 208 209 int _sys_exec_application( char* name ); 210 211 int _sys_context_switch(); 212 213 int _sys_local_task_id(); 214 215 int _sys_global_task_id(); 216 217 int _sys_thread_id(); 218 219 int _sys_procs_number( unsigned int* x_size, 252 extern int _sys_procs_number( unsigned int* x_size, 220 253 unsigned int* y_size, 221 254 unsigned int* nprocs ); 222 255 223 int _sys_vseg_get_vbase( char* vspace_name,256 extern int _sys_vseg_get_vbase( char* vspace_name, 224 257 char* vseg_name, 225 258 unsigned int* vbase ); 226 259 227 int _sys_vseg_get_length( char* vspace_name,260 extern int _sys_vseg_get_length( char* vspace_name, 228 261 char* vseg_name, 229 262 unsigned int* length ); 230 263 231 int _sys_xy_from_ptr( void* ptr,264 extern int _sys_xy_from_ptr( void* ptr, 232 265 unsigned int* x, 233 266 unsigned int* y ); 234 267 235 int _sys_heap_info( unsigned int* vaddr,268 extern int _sys_heap_info( unsigned int* vaddr, 236 269 unsigned int* length, 237 270 unsigned int x, 238 271 unsigned int y ); 239 240 int _sys_tasks_status();241 242 int _sys_fat_read( unsigned int fd_id,243 unsigned int buffer,244 unsigned int count );245 272 246 273 #endif -
soft/giet_vm/giet_libs/malloc.c
r686 r709 98 98 99 99 // checking heap segment constraints 100 if ( heap_size == 0 ) // heap segment exist 101 { 102 giet_exit("ERROR in malloc() : heap not found \n"); 103 } 104 if ( heap_size != (1<<heap_index) ) // heap size power of 2 105 { 106 giet_exit("ERROR in malloc() : heap size must be power of 2\n"); 107 } 108 if ( heap_base % heap_size ) // heap segment aligned 109 { 110 giet_exit("ERROR in malloc() : heap segment must be aligned\n"); 111 } 100 giet_pthread_assert( (heap_size != 0) , 101 "error in heap_init() : heap not found"); 102 giet_pthread_assert( (heap_size == (1<<heap_index)) , 103 "error in heap_init() : heap size must be power of 2"); 104 giet_pthread_assert( (heap_base%heap_size == 0) , 105 "error in heap_init() : heap segment must be aligned\n"); 112 106 113 107 // compute size of block containin alloc[] array … … 231 225 232 226 // checking arguments 233 if (size == 0) 234 { 235 giet_exit("\nERROR in remote_malloc() : requested size = 0 \n"); 236 } 237 if ( x >= X_SIZE ) 238 { 239 giet_exit("\nERROR in remote_malloc() : x coordinate too large\n"); 240 } 241 if ( y >= Y_SIZE ) 242 { 243 giet_exit("\nERROR in remote_malloc() : y coordinate too large\n"); 244 } 245 246 // checking initialization 247 if ( heap[x][y].init != HEAP_INITIALIZED ) 248 { 249 giet_exit("\nERROR in remote_malloc() : heap not initialized\n"); 250 } 227 giet_pthread_assert( (size != 0) , 228 "error in remote_malloc() : requested size = 0 \n"); 229 giet_pthread_assert( (x < X_SIZE) , 230 "error in remote_malloc() : x coordinate too large\n"); 231 giet_pthread_assert( (y < Y_SIZE) , 232 "error in remote_malloc() : y coordinate too large\n"); 233 giet_pthread_assert( (heap[x][y].init == HEAP_INITIALIZED) , 234 "error in remote_malloc() : heap not initialized\n"); 251 235 252 236 // normalize size … … 265 249 266 250 // check block found 267 if ( base == 0)251 if (base == 0) 268 252 { 269 253 lock_release( &heap[x][y].lock ); 270 giet_ exit("\nERROR in remote_malloc() : no more space\n");254 giet_pthread_assert( 0 , "error in remote_malloc() : no more space\n" ); 271 255 } 272 256 … … 279 263 { 280 264 lock_release( &heap[x][y].lock ); 281 giet_ exit("\nERROR in remote_malloc() : block already allocated ???\n");265 giet_pthread_assert( 0 , "error in remote_malloc() : block already allocated"); 282 266 } 283 267 … … 390 374 // check ptr value 391 375 unsigned int base = (unsigned int)ptr; 392 if ( (base < heap[x][y].heap_base) || 393 (base >= (heap[x][y].heap_base + heap[x][y].heap_size)) ) 394 { 395 giet_exit("ERROR in free() : illegal pointer for released block"); 396 } 376 giet_pthread_assert( (base >= heap[x][y].heap_base) && 377 (base < (heap[x][y].heap_base + heap[x][y].heap_size)) , 378 "error in free() : illegal pointer for released block" ); 397 379 398 380 // get the lock protecting heap[x][y] … … 410 392 { 411 393 lock_release( &heap[x][y].lock ); 412 giet_ exit("\nERROR in free() : released block not allocated ???\n");394 giet_pthread_assert( 0 , "error in free() : released block not allocated"); 413 395 } 414 396 … … 416 398 if ( base % (1 << size_index) ) 417 399 { 418 giet_exit("\nERROR in free() : released block not aligned\n"); 400 lock_release( &heap[x][y].lock ); 401 giet_pthread_assert( 0 , "error in free() : released block not aligned"); 419 402 } 420 403 -
soft/giet_vm/giet_libs/malloc.h
r686 r709 68 68 #define HEAP_INITIALIZED 0xDEADBEEF 69 69 70 #define MIN_BLOCK_SIZE 0x 8070 #define MIN_BLOCK_SIZE 0x40 71 71 72 72 //////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_libs/stdio.c
r689 r709 11 11 12 12 ////////////////////////////////////////////////////////////////////////////// 13 // /////////////////// MIPS32 related system calls ///////////////////////13 // MIPS32 related system calls 14 14 ////////////////////////////////////////////////////////////////////////////// 15 15 … … 49 49 50 50 ////////////////////////////////////////////////////////////////////////////// 51 // /////////////////// Task related system calls /////////////////////////////51 // Threads related system calls 52 52 ////////////////////////////////////////////////////////////////////////////// 53 53 54 //////////////////////////////// 55 unsigned int giet_proc_task_id() 56 { 57 return (unsigned int)sys_call( SYSCALL_LOCAL_TASK_ID, 58 0, 0, 0, 0 ); 59 } 60 61 ////////////////////////////////// 62 unsigned int giet_global_task_id() 63 { 64 return (unsigned int)sys_call( SYSCALL_GLOBAL_TASK_ID, 65 0, 0, 0, 0 ); 66 } 67 68 ///////////////////////////// 69 unsigned int giet_thread_id() 70 { 71 return (unsigned int)sys_call( SYSCALL_THREAD_ID, 72 0, 0, 0, 0 ); 73 } 74 75 ////////////////////////////// 76 void giet_exit( char* string ) 77 { 78 sys_call( SYSCALL_EXIT, 54 #define THREAD_CMD_PAUSE 0 55 #define THREAD_CMD_RESUME 1 56 #define THREAD_CMD_CONTEXT 2 57 58 ////////////////////////////////////////////////////////// 59 int giet_pthread_create( pthread_t* buffer, 60 pthread_attr_t* attr, 61 void* function, 62 void* arg ) 63 { 64 return sys_call( SYSCALL_PTHREAD_CREATE, 65 (unsigned int)buffer, 66 (unsigned int)attr, 67 (unsigned int)function, 68 (unsigned int)arg ); 69 } 70 71 ////////////////////////////////////// 72 void giet_pthread_exit( void* string ) 73 { 74 sys_call( SYSCALL_PTHREAD_EXIT, 79 75 (unsigned int)string, 80 76 0, 0, 0 ); 81 77 } 82 78 83 ///////////////////////////////////////// 84 void giet_assert( unsigned int condition, 85 char* string ) 86 { 87 if ( condition == 0 ) giet_exit( string ); 88 } 89 90 ////////////////////////// 91 void giet_context_switch() 92 { 93 sys_call( SYSCALL_CTX_SWITCH, 79 //////////////////////////////////////// 80 int giet_pthread_join( pthread_t trdid, 81 void** ptr ) 82 { 83 return sys_call( SYSCALL_PTHREAD_JOIN, 84 trdid, 85 (unsigned int)ptr, 86 0, 0 ); 87 } 88 89 /////////////////////////////////////// 90 int giet_pthread_kill( pthread_t trdid, 91 int signal ) 92 { 93 return sys_call( SYSCALL_PTHREAD_KILL, 94 trdid, 95 signal, 96 0, 0 ); 97 } 98 99 ///////////////////////// 100 void giet_pthread_yield() 101 { 102 sys_call( SYSCALL_PTHREAD_YIELD, 94 103 0, 0, 0, 0 ); 95 104 } 96 105 97 //////////////////////// 98 void giet_tasks_status() 99 { 100 sys_call( SYSCALL_TASKS_STATUS, 101 0, 0, 0, 0 ); 102 } 106 ///////////////////////////////////////////////// 107 void giet_pthread_assert( unsigned int condition, 108 char* string ) 109 { 110 if ( condition == 0 ) giet_pthread_exit( string ); 111 } 112 113 ////////////////////////////////////////////// 114 int giet_pthread_pause( char* vspace_name, 115 char* thread_name ) 116 { 117 return sys_call( SYSCALL_PTHREAD_CONTROL, 118 THREAD_CMD_PAUSE, 119 (unsigned int) vspace_name, 120 (unsigned int) thread_name, 121 0 ); 122 } 123 124 /////////////////////////////////////////////// 125 int giet_pthread_resume( char* vspace_name, 126 char* thread_name ) 127 { 128 return sys_call( SYSCALL_PTHREAD_CONTROL, 129 THREAD_CMD_RESUME, 130 (unsigned int) vspace_name, 131 (unsigned int) thread_name, 132 0 ); 133 } 134 135 /////////////////////////////////////////////// 136 int giet_pthread_context( char* vspace_name, 137 char* thread_name ) 138 { 139 return sys_call( SYSCALL_PTHREAD_CONTROL, 140 THREAD_CMD_CONTEXT, 141 (unsigned int) vspace_name, 142 (unsigned int) thread_name, 143 0 ); 144 } 145 103 146 104 147 ////////////////////////////////////////////////////////////////////////////// 105 // /////////////////// Applications system calls /////////////////////////////148 // Applications related system calls 106 149 ////////////////////////////////////////////////////////////////////////////// 107 150 … … 122 165 } 123 166 167 /////////////////////////////// 168 void giet_applications_status() 169 { 170 sys_call( SYSCALL_APPS_STATUS, 171 0, 0, 0, 0 ); 172 } 173 124 174 ////////////////////////////////////////////////////////////////////////////// 125 // /////////////////// Coprocessors system calls ////////////////////////////175 // Coprocessors related system calls 126 176 ////////////////////////////////////////////////////////////////////////////// 127 177 … … 134 184 (unsigned int)coproc_info, 135 185 0, 0 ) ) 136 giet_ exit("error in giet_coproc_alloc()");186 giet_pthread_exit("error in giet_coproc_alloc()"); 137 187 } 138 188 … … 143 193 coproc_reg_index, 144 194 0, 0, 0 ) ) 145 giet_ exit("error in giet_coproc_release()");195 giet_pthread_exit("error in giet_coproc_release()"); 146 196 } 147 197 … … 154 204 (unsigned int)desc, 155 205 0, 0 ) ) 156 giet_ exit("error in giet_coproc_channel_init()");206 giet_pthread_exit("error in giet_coproc_channel_init()"); 157 207 } 158 208 … … 163 213 coproc_reg_index, 164 214 0, 0, 0 ) ) 165 giet_ exit("error in giet_coproc_run()");215 giet_pthread_exit("error in giet_coproc_run()"); 166 216 } 167 217 … … 171 221 if ( sys_call( SYSCALL_COPROC_COMPLETED, 172 222 0, 0, 0, 0 ) ) 173 giet_ exit("error in giet_coproc_completed");223 giet_pthread_exit("error in giet_coproc_completed"); 174 224 } 175 225 176 226 177 227 ////////////////////////////////////////////////////////////////////////////// 178 // /////////////////// TTY device related system calls ///////////////////////228 // TTY device related system calls 179 229 ////////////////////////////////////////////////////////////////////////////// 180 230 … … 184 234 if ( sys_call( SYSCALL_TTY_ALLOC, 185 235 shared, 186 0, 0, 0 ) ) giet_ exit("error in giet_tty_alloc()");236 0, 0, 0 ) ) giet_pthread_exit("error in giet_tty_alloc()"); 187 237 } 188 238 … … 516 566 if (ret) 517 567 { 518 giet_ exit("ERRORin giet_tty_printf()");568 giet_pthread_exit("error in giet_tty_printf()"); 519 569 } 520 570 } // end giet_tty_printf() … … 532 582 0xFFFFFFFF, // channel index from task context 533 583 0); 534 if ( ret < 0 ) giet_ exit("error in giet_tty_getc()");584 if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getc()"); 535 585 } 536 586 while (ret != 1); … … 556 606 0xFFFFFFFF, // channel index from task context 557 607 0); 558 if ( ret < 0 ) giet_ exit("error in giet_tty_gets()");608 if ( ret < 0 ) giet_pthread_exit("error in giet_tty_gets()"); 559 609 } 560 610 while (ret != 1); … … 578 628 0XFFFFFFFF, // channel index from task context 579 629 0 ); 580 if ( ret < 0 ) giet_ exit("error in giet_tty_gets()");630 if ( ret < 0 ) giet_pthread_exit("error in giet_tty_gets()"); 581 631 } 582 632 } … … 595 645 0XFFFFFFFF, // channel index from task context 596 646 0 ); 597 if ( ret < 0 ) giet_ exit("error in giet_tty_gets()");647 if ( ret < 0 ) giet_pthread_exit("error in giet_tty_gets()"); 598 648 599 649 } … … 628 678 0xFFFFFFFF, // channel index from task context 629 679 0); 630 if ( ret < 0 ) giet_ exit("error in giet_tty_getw()");680 if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()"); 631 681 } 632 682 while (ret != 1); … … 644 694 0xFFFFFFFF, // channel index from task context 645 695 0 ); 646 if ( ret < 0 ) giet_ exit("error in giet_tty_getw()");696 if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()"); 647 697 } 648 698 else if (string_byte == 0x0A) // LF character … … 662 712 0xFFFFFFFF, // channel index from task context 663 713 0 ); 664 if ( ret < 0 ) giet_ exit("error in giet_tty_getw()");714 if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()"); 665 715 } 666 716 } … … 701 751 0xFFFFFFFF, // channel index from task context 702 752 0 ); 703 if ( ret < 0 ) giet_ exit("error in giet_tty_getw()");753 if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()"); 704 754 } 705 755 // echo character '0' … … 710 760 0xFFFFFFFF, // channel index from task context 711 761 0 ); 712 if ( ret < 0 ) giet_ exit("error in giet_tty_getw()");762 if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()"); 713 763 714 764 // return 0 value … … 719 769 720 770 ////////////////////////////////////////////////////////////////////////////////// 721 // /////////////////// TIMER related system calls ////////////////////////////////771 // TIMER related system calls 722 772 ////////////////////////////////////////////////////////////////////////////////// 723 773 … … 726 776 { 727 777 if ( sys_call( SYSCALL_TIM_ALLOC, 728 0, 0, 0, 0 ) ) giet_ exit("error in giet_timer_alloc()");778 0, 0, 0, 0 ) ) giet_pthread_exit("error in giet_timer_alloc()"); 729 779 } 730 780 … … 734 784 if ( sys_call( SYSCALL_TIM_START, 735 785 period, 736 0, 0, 0 ) ) giet_ exit("error in giet_timer_start()");786 0, 0, 0 ) ) giet_pthread_exit("error in giet_timer_start()"); 737 787 } 738 788 … … 741 791 { 742 792 if ( sys_call( SYSCALL_TIM_STOP, 743 0, 0, 0, 0 ) ) giet_ exit("error in giet_timer_stop()");793 0, 0, 0, 0 ) ) giet_pthread_exit("error in giet_timer_stop()"); 744 794 } 745 795 746 796 747 797 ////////////////////////////////////////////////////////////////////////////////// 748 // ///////////// Frame buffer device related system calls ///////////////////////798 // Frame buffer related system calls 749 799 ////////////////////////////////////////////////////////////////////////////////// 750 800 … … 753 803 { 754 804 if ( sys_call( SYSCALL_FBF_CMA_ALLOC, 755 0, 0, 0, 0 ) ) giet_ exit("error in giet_fbf_cma_alloc()");805 0, 0, 0, 0 ) ) giet_pthread_exit("error in giet_fbf_cma_alloc()"); 756 806 } 757 807 … … 766 816 (unsigned int)buf1_vbase, 767 817 (unsigned int)sts0_vaddr, 768 (unsigned int)sts1_vaddr ) ) giet_ exit("error in giet_fbf_cma_init_buf()");818 (unsigned int)sts1_vaddr ) ) giet_pthread_exit("error in giet_fbf_cma_init_buf()"); 769 819 } 770 820 … … 774 824 if ( sys_call( SYSCALL_FBF_CMA_START, 775 825 length, 776 0, 0, 0 ) ) giet_ exit("error in giet_fbf_cma_start()");826 0, 0, 0 ) ) giet_pthread_exit("error in giet_fbf_cma_start()"); 777 827 } 778 828 … … 782 832 if ( sys_call( SYSCALL_FBF_CMA_DISPLAY, 783 833 buffer, 784 0, 0, 0 ) ) giet_ exit("error in giet_fbf_cma_display()");834 0, 0, 0 ) ) giet_pthread_exit("error in giet_fbf_cma_display()"); 785 835 } 786 836 … … 789 839 { 790 840 if ( sys_call( SYSCALL_FBF_CMA_STOP, 791 0, 0, 0, 0 ) ) giet_ exit("error in giet_fbf_cma_stop()");841 0, 0, 0, 0 ) ) giet_pthread_exit("error in giet_fbf_cma_stop()"); 792 842 } 793 843 … … 801 851 (unsigned int)buffer, 802 852 length, 803 0 ) ) giet_ exit("error in giet_fbf_sync_write()");853 0 ) ) giet_pthread_exit("error in giet_fbf_sync_write()"); 804 854 } 805 855 … … 813 863 (unsigned int)buffer, 814 864 length, 815 0 ) ) giet_ exit("error in giet_fbf_sync_read()");865 0 ) ) giet_pthread_exit("error in giet_fbf_sync_read()"); 816 866 } 817 867 818 868 819 869 ////////////////////////////////////////////////////////////////////////////////// 820 // ///////////////////// NIC related system calls /////////////////////////////////870 // NIC related system calls 821 871 ////////////////////////////////////////////////////////////////////////////////// 822 872 823 //////////////////////////////////////////////////// 824 unsigned int giet_nic_rx_alloc( unsigned int xmax, 825 unsigned int ymax ) 826 { 827 int channel = sys_call( SYSCALL_NIC_ALLOC, 828 1, 829 xmax, 830 ymax, 831 0 ); 832 if ( channel < 0 ) giet_exit("error in giet_nic_rx_alloc()"); 833 834 return (unsigned int)channel; 835 } 836 837 //////////////////////////////////////////////////// 838 unsigned int giet_nic_tx_alloc( unsigned int xmax, 839 unsigned int ymax ) 840 { 841 int channel = sys_call( SYSCALL_NIC_ALLOC, 842 0, 843 xmax, 844 ymax, 845 0 ); 846 if ( channel < 0 ) giet_exit("error in giet_nic_tx_alloc()"); 847 848 return (unsigned int)channel; 849 } 850 851 ////////////////////////////////////////////// 852 void giet_nic_rx_start( unsigned int channel ) 873 ////////////////////////////////////////// 874 void giet_nic_rx_alloc( unsigned int xmax, 875 unsigned int ymax ) 876 { 877 if ( sys_call( SYSCALL_NIC_ALLOC, 878 1, // RX 879 xmax, 880 ymax, 881 0 ) ) giet_pthread_exit("error in giet_nic_rx_alloc()"); 882 } 883 884 ////////////////////////////////////////// 885 void giet_nic_tx_alloc( unsigned int xmax, 886 unsigned int ymax ) 887 { 888 if ( sys_call( SYSCALL_NIC_ALLOC, 889 0, // TX 890 xmax, 891 ymax, 892 0 ) ) giet_pthread_exit("error in giet_nic_tx_alloc()"); 893 } 894 895 //////////////////////// 896 void giet_nic_rx_start() 853 897 { 854 898 if ( sys_call( SYSCALL_NIC_START, 855 1, 856 channel, 857 0, 0 ) ) giet_exit("error in giet_nic_rx_start()"); 858 } 859 860 ////////////////////////////////////////////// 861 void giet_nic_tx_start( unsigned int channel ) 899 1, // RX 900 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_start()"); 901 } 902 903 //////////////////////// 904 void giet_nic_tx_start() 862 905 { 863 906 if ( sys_call( SYSCALL_NIC_START, 864 0, 865 channel, 866 0, 0 ) ) giet_exit("error in giet_nic_tx_start()"); 867 } 868 869 /////////////////////////////////////////////////////////// 870 void giet_nic_rx_move( unsigned int channel, void* buffer ) 907 0, // TX 908 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_start()"); 909 } 910 911 ///////////////////////////////////// 912 void giet_nic_rx_move( void* buffer ) 871 913 { 872 914 if ( sys_call( SYSCALL_NIC_MOVE, 873 1, 874 channel, 915 1, // RX 875 916 (unsigned int)buffer, 876 0 ) ) giet_exit("error in giet_nic_rx_move()");877 } 878 879 ///////////////////////////////////// //////////////////////880 void giet_nic_tx_move( unsigned int channel,void* buffer )917 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_move()"); 918 } 919 920 ///////////////////////////////////// 921 void giet_nic_tx_move( void* buffer ) 881 922 { 882 923 if ( sys_call( SYSCALL_NIC_MOVE, 883 0, 884 channel, 924 0, // TX 885 925 (unsigned int)buffer, 886 0 ) ) giet_exit("error in giet_nic_tx_move()");887 } 888 889 /////////////////////// //////////////////////890 void giet_nic_rx_stop( unsigned int channel)926 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_move()"); 927 } 928 929 /////////////////////// 930 void giet_nic_rx_stop() 891 931 { 892 932 if ( sys_call( SYSCALL_NIC_STOP, 893 1, 894 channel, 895 0, 0 ) ) giet_exit("error in giet_nic_rx_stop()"); 896 } 897 898 ///////////////////////////////////////////// 899 void giet_nic_tx_stop( unsigned int channel ) 933 1, // RX 934 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_stop()"); 935 } 936 937 /////////////////////// 938 void giet_nic_tx_stop() 900 939 { 901 940 if ( sys_call( SYSCALL_NIC_STOP, 902 0, 903 channel, 904 0, 0 ) ) giet_exit("error in giet_nic_tx_stop()"); 905 } 906 907 ////////////////////////////////////////////// 908 void giet_nic_rx_stats( unsigned int channel ) 941 0, // TX 942 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_stop()"); 943 } 944 945 //////////////////////// 946 void giet_nic_rx_stats() 909 947 { 910 948 if ( sys_call( SYSCALL_NIC_STATS, 911 1, 912 channel, 913 0, 0 ) ) giet_exit("error in giet_nic_rx_stats()"); 914 } 915 916 ////////////////////////////////////////////// 917 void giet_nic_tx_stats( unsigned int channel ) 949 1, // RX 950 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_stats()"); 951 } 952 953 //////////////////////// 954 void giet_nic_tx_stats() 918 955 { 919 956 if ( sys_call( SYSCALL_NIC_STATS, 920 0, 921 channel, 922 0, 0 ) ) giet_exit("error in giet_nic_tx_stats()"); 923 } 924 925 ////////////////////////////////////////////// 926 void giet_nic_rx_clear( unsigned int channel ) 957 0, // TX 958 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_stats()"); 959 } 960 961 //////////////////////// 962 void giet_nic_rx_clear() 927 963 { 928 964 if ( sys_call( SYSCALL_NIC_CLEAR, 929 1, 930 channel, 931 0, 0 ) ) giet_exit("error in giet_nic_rx_clear()"); 932 } 933 934 ////////////////////////////////////////////// 935 void giet_nic_tx_clear( unsigned int channel ) 965 1, // RX 966 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_clear()"); 967 } 968 969 //////////////////////// 970 void giet_nic_tx_clear() 936 971 { 937 972 if ( sys_call( SYSCALL_NIC_CLEAR, 938 0, 939 channel, 940 0, 0 ) ) giet_exit("error in giet_nic_tx_clear()"); 973 0, // TX 974 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_clear()"); 941 975 } 942 976 … … 944 978 945 979 /////////////////////////////////////////////////////////////////////////////////// 946 // /////////////////// FAT related system calls ////////////////////////////////////980 // FAT related system calls 947 981 /////////////////////////////////////////////////////////////////////////////////// 948 982 … … 984 1018 (unsigned int)buffer, 985 1019 count, 986 0 ); 1020 0 ); // no physical addressing required 987 1021 } 988 1022 … … 996 1030 (unsigned int)buffer, 997 1031 count, 998 0 ); 1032 0 ); // no physical addressing required 999 1033 } 1000 1034 … … 1068 1102 1069 1103 ////////////////////////////////////////////////////////////////////////////////// 1070 // /////////////////// Miscellaneous system calls /////////////////////////////////1104 // Miscellaneous system calls 1071 1105 ////////////////////////////////////////////////////////////////////////////////// 1072 1106 … … 1080 1114 (unsigned int)y_size, 1081 1115 (unsigned int)nprocs, 1082 0 ) ) giet_ exit("ERRORin giet_procs_number()");1116 0 ) ) giet_pthread_exit("error in giet_procs_number()"); 1083 1117 } 1084 1118 … … 1092 1126 (unsigned int) vobj_name, 1093 1127 (unsigned int) vbase, 1094 0 ) ) giet_ exit("ERRORin giet_vobj_get_vbase()");1128 0 ) ) giet_pthread_exit("error in giet_vobj_get_vbase()"); 1095 1129 } 1096 1130 … … 1104 1138 (unsigned int) vobj_name, 1105 1139 (unsigned int) length, 1106 0 ) ) giet_ exit("ERRORin giet_vobj_get_length()");1140 0 ) ) giet_pthread_exit("error in giet_vobj_get_length()"); 1107 1141 } 1108 1142 … … 1113 1147 unsigned int y ) 1114 1148 { 1115 if (sys_call( SYSCALL_HEAP_INFO,1116 1117 1118 1119 y ) ) giet_exit("ERROR in giet_heap_info()");1149 sys_call( SYSCALL_HEAP_INFO, 1150 (unsigned int)vaddr, 1151 (unsigned int)length, 1152 x, 1153 y ); 1120 1154 } 1121 1155 … … 1129 1163 (unsigned int)px, 1130 1164 (unsigned int)py, 1131 0 ) ) giet_ exit("ERRORin giet_get_xy()");1165 0 ) ) giet_pthread_exit("error in giet_get_xy()"); 1132 1166 } 1133 1167 -
soft/giet_vm/giet_libs/stdio.h
r689 r709 14 14 15 15 #include "giet_fat32/fat32_shared.h" 16 #include "giet_common/mips32_registers.h" 16 17 17 18 // These define must be synchronised with … … 20 21 #define SYSCALL_PROC_XYP 0x00 21 22 #define SYSCALL_PROC_TIME 0x01 22 #define SYSCALL_ TTY_WRITE0x0223 #define SYSCALL_ TTY_READ0x0324 #define SYSCALL_TTY_ALLOC0x0425 #define SYSCALL_TASKS_STATUS0x0523 #define SYSCALL_PROCS_NUMBER 0x02 24 #define SYSCALL_GET_XY 0x03 25 // 0x04 26 // 0x05 26 27 // 0x06 27 28 #define SYSCALL_HEAP_INFO 0x07 28 #define SYSCALL_ LOCAL_TASK_ID0x0829 #define SYSCALL_ GLOBAL_TASK_ID0x0929 #define SYSCALL_VOBJ_GET_VBASE 0x08 30 #define SYSCALL_VOBJ_GET_LENGTH 0x09 30 31 #define SYSCALL_FBF_CMA_ALLOC 0x0A 31 32 #define SYSCALL_FBF_CMA_INIT_BUF 0x0B … … 33 34 #define SYSCALL_FBF_CMA_DISPLAY 0x0D 34 35 #define SYSCALL_FBF_CMA_STOP 0x0E 35 #define SYSCALL_EXIT0x0F36 37 #define SYSCALL_ PROCS_NUMBER0x1036 // 0x0F 37 38 #define SYSCALL_APPS_STATUS 0x10 38 39 #define SYSCALL_FBF_SYNC_WRITE 0x11 39 40 #define SYSCALL_FBF_SYNC_READ 0x12 40 #define SYSCALL_THREAD_ID0x1341 // 0x13 41 42 #define SYSCALL_TIM_ALLOC 0x14 42 43 #define SYSCALL_TIM_START 0x15 … … 44 45 #define SYSCALL_KILL_APP 0x17 45 46 #define SYSCALL_EXEC_APP 0x18 46 #define SYSCALL_CTX_SWITCH0x1947 #define SYSCALL_ VOBJ_GET_VBASE0x1A48 #define SYSCALL_ VOBJ_GET_LENGTH0x1B49 #define SYSCALL_ GET_XY0x1C50 //0x1D51 //0x1E52 //0x1F47 // 0x19 48 #define SYSCALL_PTHREAD_CONTROL 0x1A 49 #define SYSCALL_PTHREAD_YIELD 0x1B 50 #define SYSCALL_PTHREAD_KILL 0x1C 51 #define SYSCALL_PTHREAD_CREATE 0x1D 52 #define SYSCALL_PTHREAD_JOIN 0x1E 53 #define SYSCALL_PTHREAD_EXIT 0x1F 53 54 54 55 #define SYSCALL_FAT_OPEN 0x20 … … 75 76 #define SYSCALL_NIC_STATS 0x34 76 77 #define SYSCALL_NIC_CLEAR 0x35 77 //0x3678 //0x3779 //0x3878 #define SYSCALL_TTY_WRITE 0x36 79 #define SYSCALL_TTY_READ 0x37 80 #define SYSCALL_TTY_ALLOC 0x38 80 81 // 0x39 81 82 // 0x3A … … 152 153 153 154 ////////////////////////////////////////////////////////////////////////// 154 // Task related system calls 155 ////////////////////////////////////////////////////////////////////////// 156 157 extern unsigned int giet_proc_task_id(); 158 159 extern unsigned int giet_global_task_id(); 160 161 extern unsigned int giet_thread_id(); 162 163 extern void giet_exit( char* string ); 164 165 extern void giet_assert( unsigned int condition, 166 char* string ); 167 168 extern void giet_context_switch(); 169 170 extern void giet_tasks_status(); 155 // Threads related system calls 156 ////////////////////////////////////////////////////////////////////////// 157 158 typedef unsigned int pthread_t; 159 160 typedef unsigned int pthread_attr_t; 161 162 extern int giet_pthread_create( pthread_t* trdid, 163 pthread_attr_t* attr, 164 void* function, 165 void* ptr ); 166 167 extern void giet_pthread_exit( void* string ); 168 169 extern int giet_pthread_join( pthread_t trdid, 170 void** ptr ); 171 172 extern int giet_pthread_kill( pthread_t thread_id, 173 int signal ); 174 175 extern void giet_pthread_yield(); 176 177 extern void giet_pthread_assert( unsigned int condition, 178 char* string ); 179 180 extern int giet_pthread_pause( char* vspace, 181 char* thread ); 182 183 extern int giet_pthread_resume( char* vspace, 184 char* thread ); 185 186 extern int giet_pthread_context( char* vspace, 187 char* thread ); 171 188 172 189 ////////////////////////////////////////////////////////////////////////// … … 177 194 178 195 extern int giet_exec_application( char* name ); 196 197 extern void giet_applications_status(); 179 198 180 199 ////////////////////////////////////////////////////////////////////////// … … 258 277 ////////////////////////////////////////////////////////////////////////// 259 278 260 extern unsigned intgiet_nic_rx_alloc( unsigned int xmax, unsigned int ymax );261 262 extern unsigned intgiet_nic_tx_alloc( unsigned int xmax, unsigned int ymax );263 264 extern void giet_nic_rx_start( unsigned int channel);265 266 extern void giet_nic_tx_start( unsigned int channel);267 268 extern void giet_nic_rx_move( unsigned int channel,void* buffer );269 270 extern void giet_nic_tx_move( unsigned int channel,void* buffer );271 272 extern void giet_nic_rx_stop( unsigned int channel);273 274 extern void giet_nic_tx_stop( unsigned int channel);275 276 extern void giet_nic_rx_stats( unsigned int channel);277 278 extern void giet_nic_tx_stats( unsigned int channel);279 280 extern void giet_nic_rx_clear( unsigned int channel);281 282 extern void giet_nic_tx_clear( unsigned int channel);279 extern void giet_nic_rx_alloc( unsigned int xmax, unsigned int ymax ); 280 281 extern void giet_nic_tx_alloc( unsigned int xmax, unsigned int ymax ); 282 283 extern void giet_nic_rx_start(); 284 285 extern void giet_nic_tx_start(); 286 287 extern void giet_nic_rx_move( void* buffer ); 288 289 extern void giet_nic_tx_move( void* buffer ); 290 291 extern void giet_nic_rx_stop(); 292 293 extern void giet_nic_tx_stop(); 294 295 extern void giet_nic_rx_stats(); 296 297 extern void giet_nic_tx_stats(); 298 299 extern void giet_nic_rx_clear(); 300 301 extern void giet_nic_tx_clear(); 283 302 284 303 ////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_libs/user_barrier.c
r693 r709 208 208 { 209 209 // check parameters 210 if ( x_size > 16 ) giet_exit("SQT BARRIER ERROR : x_size too large");211 if ( y_size > 16 ) giet_exit("SQT BARRIER ERROR : y_size too large");212 if ( ntasks > 8 ) giet_exit("SQT BARRIER ERROR : ntasks too large");210 giet_pthread_assert( (x_size <= 16) , "SQT BARRIER ERROR : x_size too large" ); 211 giet_pthread_assert( (y_size <= 16) , "SQT BARRIER ERROR : y_size too large" ); 212 giet_pthread_assert( (ntasks <= 8 ) , "SQT BARRIER ERROR : ntasks too large" ); 213 213 214 214 // compute SQT levels -
soft/giet_vm/giet_libs/user_lock.c
r693 r709 9 9 10 10 #include "user_lock.h" 11 #include "malloc.h" 11 12 #include "giet_config.h" 12 13 #include "stdio.h" 13 14 14 15 ////////////////////////////////////////////////////////////////////////////////// 15 // This function uses LL/SC to make an atomic increment.16 // atomic access functions 16 17 ////////////////////////////////////////////////////////////////////////////////// 18 19 ////////////////////////////////////////////////// 17 20 unsigned int atomic_increment( unsigned int* ptr, 18 21 unsigned int increment ) … … 37 40 38 41 /////////////////////////////////////////////////////////////////////////////////// 39 // This blocking function returns only when the lock has been taken. 40 /////////////////////////////////////////////////////////////////////////////////// 42 // simple lock access functions 43 /////////////////////////////////////////////////////////////////////////////////// 44 45 ////////////////////////////////////// 41 46 void lock_acquire( user_lock_t* lock ) 42 47 { … … 49 54 unsigned int lpid; 50 55 giet_proc_xyp( &x, &y, &lpid ); 51 giet_tty_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] get ticket = %d"56 giet_tty_printf("\n[USER_LOCK DEBUG] lock_acquire() : P[%d,%d,%d] get ticket = %d" 52 57 " for lock %x at cycle %d (current = %d / free = %d)\n", 53 58 x, y, lpid, ticket, … … 65 70 66 71 #if GIET_DEBUG_USER_LOCK 67 giet_tty_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] get lock %x"72 giet_tty_printf("\n[USER_LOCK DEBUG] lock_acquire() : P[%d,%d,%d] get lock %x" 68 73 " at cycle %d (current = %d / free = %d)\n", 69 74 x, y, lpid, (unsigned int)lock, … … 73 78 } 74 79 75 ////////////////////////////////////////////////////////////////////////////// 76 // This function releases the lock. 77 ////////////////////////////////////////////////////////////////////////////// 80 ////////////////////////////////////// 78 81 void lock_release( user_lock_t* lock ) 79 82 { … … 87 90 unsigned int lpid; 88 91 giet_proc_xyp( &x, &y, &lpid ); 89 giet_tty_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] release lock %x"92 giet_tty_printf("\n[USER_LOCK DEBUG] lock_release() : P[%d,%d,%d] release lock %x" 90 93 " at cycle %d (current = %d / free = %d)\n", 91 94 x, y, lpid, (unsigned int)lock, … … 95 98 } 96 99 97 ////////////////////////////////////////////////////////////////////////////// 98 // This function initializes the lock. 99 ////////////////////////////////////////////////////////////////////////////// 100 /////////////////////////////////// 100 101 void lock_init( user_lock_t* lock ) 101 102 { … … 108 109 unsigned int lpid; 109 110 giet_proc_xyp( &x, &y, &lpid ); 110 giet_tty_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] init lock %x"111 giet_tty_printf("\n[USER_LOCK DEBUG] lock_init() : P[%d,%d,%d] init lock %x" 111 112 " at cycle %d (current = %d / free = %d)\n", 112 113 x, y, lpid, (unsigned int)lock, … … 114 115 #endif 115 116 117 } 118 119 /////////////////////////////////////////////////////////////////////////////////// 120 // SQT lock access functions 121 /////////////////////////////////////////////////////////////////////////////////// 122 123 ////////////////////////////////////////////////// 124 static void sqt_lock_build( sqt_lock_t* lock, // pointer on the SQT lock 125 unsigned int x, // node X coordinate 126 unsigned int y, // node Y coordinate 127 unsigned int level, // node level 128 sqt_lock_node_t* parent, // pointer on parent node 129 unsigned int xmax, // SQT X size 130 unsigned int ymax ) // SQT Y size 131 { 132 133 #if GIET_DEBUG_USER_LOCK 134 unsigned int px; 135 unsigned int py; 136 unsigned int pl; 137 giet_proc_xyp( &px, &py, &pl ); 138 #endif 139 140 // get target node pointer 141 sqt_lock_node_t* node = lock->node[x][y][level]; 142 143 if (level == 0 ) // terminal case 144 { 145 // initializes target node 146 node->current = 0; 147 node->free = 0; 148 node->level = 0; 149 node->parent = parent; 150 node->child[0] = NULL; 151 node->child[1] = NULL; 152 node->child[2] = NULL; 153 node->child[3] = NULL; 154 155 #if GIET_DEBUG_USER_LOCK 156 giet_tty_printf("\n[USER_LOCK DEBUG] sqt_lock_build() : " 157 "P[%d,%d,%d] initialises SQT node[%d,%d,%d] = %x :\n" 158 " parent = %x / child0 = %x / child1 = %x / child2 = %x / child3 = %x\n", 159 px , py , pl , x , y , level , (unsigned int)node , 160 (unsigned int)node->parent , 161 (unsigned int)node->child[0] , 162 (unsigned int)node->child[1] , 163 (unsigned int)node->child[2] , 164 (unsigned int)node->child[3] ); 165 #endif 166 167 } 168 else // non terminal case 169 { 170 unsigned int cx[4]; // x coordinate for children 171 unsigned int cy[4]; // y coordinate for children 172 unsigned int i; // child index 173 174 // the child0 coordinates are equal to the parent coordinates 175 // other childs coordinates are incremented depending on the level value 176 cx[0] = x; 177 cy[0] = y; 178 179 cx[1] = x + (1 << (level-1)); 180 cy[1] = y; 181 182 cx[2] = x; 183 cy[2] = y + (1 << (level-1)); 184 185 cx[3] = x + (1 << (level-1)); 186 cy[3] = y + (1 << (level-1)); 187 188 // initializes target node 189 for ( i = 0 ; i < 4 ; i++ ) 190 { 191 if ( (cx[i] < xmax) && (cy[i] < ymax) ) 192 node->child[i] = lock->node[cx[i]][cy[i]][level-1]; 193 else 194 node->child[i] = NULL; 195 } 196 node->current = 0; 197 node->free = 0; 198 node->level = level; 199 node->parent = parent; 200 201 #if GIET_DEBUG_USER_LOCK 202 giet_tty_printf("\n[USER_LOCK DEBUG] sqt_lock_init() : " 203 "P[%d,%d,%d] initialises SQT node[%d,%d,%d] : \n" 204 " parent = %x / childO = %x / child1 = %x / child2 = %x / child3 = %x\n", 205 px , py , pl , x , y , level , 206 (unsigned int)node->parent , 207 (unsigned int)node->child[0] , 208 (unsigned int)node->child[1] , 209 (unsigned int)node->child[2] , 210 (unsigned int)node->child[3] ); 211 #endif 212 213 // recursive calls for children nodes 214 for ( i = 0 ; i < 4 ; i++ ) 215 { 216 if ( (cx[i] < xmax) && (cy[i] < ymax) ) 217 sqt_lock_build( lock, 218 cx[i], 219 cy[i], 220 level-1, 221 node, 222 xmax, 223 ymax ); 224 } 225 } 226 } // end _sqt_lock_build() 227 228 229 230 ////////////////////////////////////// 231 void sqt_lock_init( sqt_lock_t* lock, 232 unsigned int x_size, // number of clusters in a row 233 unsigned int y_size, // number of clusters in a col 234 unsigned int nthreads ) // threads per clusters 235 { 236 // check parameters 237 if ( x_size > 16 ) giet_pthread_exit("SQT LOCK ERROR : x_size too large"); 238 if ( y_size > 16 ) giet_pthread_exit("SQT LOCK ERROR : y_size too large"); 239 if ( nthreads > 8 ) giet_pthread_exit("SQT LOCK ERROR : nthreads too large"); 240 241 // compute SQT levels 242 unsigned int levels; 243 unsigned int z = (x_size > y_size) ? x_size : y_size; 244 levels = (z < 2) ? 1 : (z < 3) ? 2 : (z < 5) ? 3 : (z < 9) ? 4 : 5; 245 246 #if GIET_DEBUG_USER_LOCK 247 unsigned int px; 248 unsigned int py; 249 unsigned int pp; 250 giet_proc_xyp(&px, &py, &pp); 251 unsigned int side = (z < 2) ? 1 : (z < 3) ? 2 : (z < 5) ? 4 : (z < 9) ? 8 : 16; 252 giet_tty_printf("\n[USER_LOCK DEBUG] sqt_lock_init() : " 253 "P[%d,%d%d] makes sqt_nodes allocation for lock %x\n" 254 " x_size = %d / y_size = %d / levels = %d / side = %d\n", 255 px, py, pp, (unsigned int) lock, x_size , y_size , levels , side ); 256 #endif 257 258 259 unsigned int x; // x coordinate for one SQT node 260 unsigned int y; // y coordinate for one SQT node 261 unsigned int l; // level for one SQT node 262 263 for ( x = 0 ; x < x_size ; x++ ) 264 { 265 for ( y = 0 ; y < y_size ; y++ ) 266 { 267 for ( l = 0 ; l < levels ; l++ ) // level 0 nodes 268 { 269 270 if ( ( (l == 0) && ((x&0x00) == 0) && ((y&0x00) == 0) ) || 271 ( (l == 1) && ((x&0x01) == 0) && ((y&0x01) == 0) ) || 272 ( (l == 2) && ((x&0x03) == 0) && ((y&0x03) == 0) ) || 273 ( (l == 3) && ((x&0x07) == 0) && ((y&0x07) == 0) ) || 274 ( (l == 4) && ((x&0x0F) == 0) && ((y&0x0F) == 0) ) ) 275 { 276 lock->node[x][y][l] = 277 (sqt_lock_node_t*)remote_malloc( sizeof(sqt_lock_node_t), 278 x, y ); 279 280 #if GIET_DEBUG_USER_LOCK 281 giet_tty_printf("\n[USER_LOCK DEBUG] squt_lock_init() : " 282 "P[%d,%d,%d] allocates SQT node[%d,%d,%d] = %x\n", 283 px , py , pp , x , y , l , (unsigned int)lock->node[x][y][l] ); 284 #endif 285 } 286 } 287 } 288 } 289 290 // recursively initialize all SQT nodes from root to bottom 291 sqt_lock_build( lock, 292 0, 293 0, 294 levels-1, 295 NULL, 296 x_size, 297 y_size ); 298 299 asm volatile ("sync" ::: "memory"); 300 301 #if GIET_DEBUG_USER_LOCK 302 giet_tty_printf("\n[USER_LOCK DEBUG] sqt_lock_init() : " 303 "P[%d,%d,%d] completes SQT nodes initialisation\n", px, py, pp); 304 #endif 305 306 } // end sqt_lock_init() 307 308 309 ////////////////////////////////////////////////// 310 static void sqt_lock_take( sqt_lock_node_t* node ) 311 { 312 // get next free ticket from local lock 313 unsigned int ticket = atomic_increment( &node->free, 1 ); 314 315 #if GIET_DEBUG_USER_LOCK 316 unsigned int x; 317 unsigned int y; 318 unsigned int l; 319 giet_proc_xyp(&x, &y, &l); 320 giet_tty_printf("\n[USER_LOCK DEBUG] sqt_lock_take() : " 321 "P[%d,%d,%d] get ticket %d for SQT lock %x" 322 " / level = %d / current = %d / free = %d\n", 323 x , y , l , ticket , (unsigned int)node , 324 node->level , node->current , node->free ); 325 #endif 326 327 // poll the local lock current index 328 while ( (*(volatile unsigned int *)( &node->current )) != ticket ) asm volatile( "nop" ); 329 330 #if GIET_DEBUG_USER_LOCK 331 giet_tty_printf("\n[DEBUG SQT_LOCK] sqt_lock_take() : " 332 "P[%d,%d,%d] get SQT lock %x" 333 " / level = %d / current = %d / free = %d\n", 334 x , y , l , (unsigned int)node , 335 node->level , node->current , node->free ); 336 #endif 337 338 // try to take the parent node lock until top is reached 339 if ( node->parent != NULL ) sqt_lock_take( node->parent ); 340 341 } // end _sqt_lock_take() 342 343 344 ////////////////////////////////////////// 345 void sqt_lock_acquire( sqt_lock_t* lock ) 346 { 347 unsigned int x; 348 unsigned int y; 349 unsigned int p; 350 351 // get cluster coordinates 352 giet_proc_xyp( &x, &y, &p ); 353 354 #if GIET_DEBUG_USER_LOCK 355 giet_tty_printf("\n[DEBUG SQT_LOCK] sqt_lock_acquire() : " 356 "P[%d,%d,%d] try to take lock = %x / lock_node = %x\n", 357 x, y, p, lock, lock->node[x][y][0] ); 358 #endif 359 360 // try to recursively take the distributed locks (from bottom to top) 361 sqt_lock_take( lock->node[x][y][0] ); 362 } 363 364 ////////////////////////////////////////////////// 365 static void sqt_lock_give( sqt_lock_node_t* node ) 366 { 367 // release the local lock 368 node->current = node->current + 1; 369 370 #if GIET_DEBUG_USER_LOCK 371 unsigned int x; 372 unsigned int y; 373 unsigned int l; 374 giet_proc_xyp(&x, &y, &l); 375 giet_tty_printf("\n[USER_LOCK DEBUG] sqt_lock_give() : " 376 "P[%d,%d,%d] release SQT lock_node %x" 377 " / level = %d / current = %d / free = %d\n", 378 x , y , l , (unsigned int)node, 379 node->level , node->current , node->free ); 380 #endif 381 382 // reset parent node until top is reached 383 if ( node->parent != NULL ) sqt_lock_give( node->parent ); 384 385 } // end _sqt_lock_give() 386 387 ////////////////////////////////////////// 388 void sqt_lock_release( sqt_lock_t* lock ) 389 { 390 asm volatile ( "sync" ); // for consistency 391 392 unsigned int x; 393 unsigned int y; 394 unsigned int p; 395 // get cluster coordinates 396 giet_proc_xyp( &x, &y, &p ); 397 398 // recursively reset the distributed locks (from bottom to top) 399 sqt_lock_give( lock->node[x][y][0] ); 116 400 } 117 401 -
soft/giet_vm/giet_libs/user_lock.h
r461 r709 8 8 /////////////////////////////////////////////////////////////////////////////////// 9 9 10 #ifndef _GIET_FILE_LOCK_H_ 11 #define _GIET_FILE_LOCK_H_ 10 #ifndef _USER_LOCK_H_ 11 #define _USER_LOCK_H_ 12 13 #include "hard_config.h" 12 14 13 15 /////////////////////////////////////////////////////////////////////////////////// 14 // lock structure16 // simple lock structure 15 17 /////////////////////////////////////////////////////////////////////////////////// 16 18 … … 23 25 24 26 /////////////////////////////////////////////////////////////////////////////////// 25 // access functions27 // simple lock access functions 26 28 /////////////////////////////////////////////////////////////////////////////////// 27 29 … … 35 37 extern void lock_init( user_lock_t * lock ); 36 38 39 /////////////////////////////////////////////////////////////////////////////////// 40 // SQT lock structures 41 /////////////////////////////////////////////////////////////////////////////////// 42 43 typedef struct sqt_lock_node_s 44 { 45 unsigned int current; // current ticket index 46 unsigned int free; // next free ticket index 47 unsigned int level; // hierarchical level (0 is bottom) 48 struct sqt_lock_node_s* parent; // parent node (NULL for root) 49 struct sqt_lock_node_s* child[4]; // children node 50 unsigned int padding[8]; // for 64 bytes alignment 51 } sqt_lock_node_t; 52 53 typedef struct sqt_lock_s 54 { 55 sqt_lock_node_t* node[X_SIZE][Y_SIZE][5]; // array of pointers on SBT nodes 56 } sqt_lock_t; 57 58 ////////////////////////////////////////////////////////////////////////////////// 59 // SQT lock access functions 60 ////////////////////////////////////////////////////////////////////////////////// 61 62 63 extern void sqt_lock_init( sqt_lock_t* lock, 64 unsigned int x_size, 65 unsigned int y_size, 66 unsigned int ntasks ); 67 68 extern void sqt_lock_acquire( sqt_lock_t* lock ); 69 70 extern void sqt_lock_release( sqt_lock_t* lock ); 71 37 72 #endif 38 73 -
soft/giet_vm/giet_python/mapping.py
r642 r709 10 10 # This file contains the classes required to define a mapping for the GIET_VM. 11 11 # - A 'Mapping' contains a set of 'Cluster' (hardware architecture) 12 # a set of 'Vseg' (kernel glo galsvirtual segments)12 # a set of 'Vseg' (kernel global virtual segments) 13 13 # a set of 'Vspace' (one or several user applications) 14 14 # - A 'Cluster' contains a set of 'Pseg' (physical segments in cluster) … … 16 16 # a set of 'Periph' (peripherals in cluster) 17 17 # - A 'Vspace' contains a set of 'Vseg' (user virtual segments) 18 # a set of 'T ask' (user parallel tasks)18 # a set of 'Thread' (POSIX thread) 19 19 # - A 'Periph' contains a set of 'Irq' (only for XCU and PIC types ) 20 20 ################################################################################### … … 22 22 # The objects used to describe a mapping are distributed in the PYTHON structure: 23 23 # For example the psegs set is split in several subsets (one subset per cluster), 24 # or the t asks set is split in several subsets (one subset per vspace), etc...24 # or the threads set is split in several subsets (one subset per vspace), etc... 25 25 # In the C binary data structure used by the giet_vm, all objects of same type 26 26 # are stored in a linear array (one single array for all psegs for example). … … 192 192 self.total_psegs = 0 193 193 self.total_vsegs = 0 194 self.total_t asks= 0194 self.total_threads = 0 195 195 self.total_procs = 0 196 196 self.total_irqs = 0 … … 406 406 return vseg 407 407 408 ################################ add a task in a vspace 409 def addTask( self, 410 vspace, # vspace containing task 411 name, # task name 412 trdid, # task index in vspace 413 x, # destination x coordinate 414 y, # destination y coordinate 415 lpid, # destination processor local index 416 stackname, # name of vseg containing stack 417 heapname, # name of vseg containing heap 418 startid ): # index in start_vector 419 420 assert (x < self.x_size) and (y < self.y_size) 421 assert lpid < self.nprocs 422 423 # add one task into mapping 424 task = Task( name, trdid, x, y, lpid, stackname, heapname, startid ) 425 vspace.tasks.append( task ) 426 task.index = self.total_tasks 427 self.total_tasks += 1 428 429 return task 408 ################################ add a thread in a vspace 409 def addThread( self, 410 vspace, # vspace containing thread 411 name, # thread name 412 is_main, # Boolean (one thread per vspace) 413 x, # destination x coordinate 414 y, # destination y coordinate 415 p, # destination processor local index 416 stackname, # name of vseg containing stack 417 heapname, # name of vseg containing heap 418 startid ): # index in start_vector 419 420 assert x < self.x_size 421 assert y < self.y_size 422 assert p < self.nprocs 423 424 # add one thread into mapping 425 thread = Thread( name, is_main, x, y, p, stackname, heapname, startid ) 426 vspace.threads.append( thread ) 427 thread.index = self.total_threads 428 self.total_threads += 1 429 430 return thread 430 431 431 432 ################################# … … 497 498 498 499 # header 499 byte_stream += self.int2bytes(4, self.signature)500 byte_stream += self.int2bytes(4, self.x_size)501 byte_stream += self.int2bytes(4, self.y_size)502 byte_stream += self.int2bytes(4, self.x_width)503 byte_stream += self.int2bytes(4, self.y_width)504 byte_stream += self.int2bytes(4, self.x_io)505 byte_stream += self.int2bytes(4, self.y_io)506 byte_stream += self.int2bytes(4, self.irq_per_proc)507 byte_stream += self.int2bytes(4, self.use_ramdisk)508 byte_stream += self.int2bytes(4, self.total_globals)509 byte_stream += self.int2bytes(4, self.total_vspaces)510 byte_stream += self.int2bytes(4, self.total_psegs)511 byte_stream += self.int2bytes(4, self.total_vsegs)512 byte_stream += self.int2bytes(4, self.total_tasks)513 byte_stream += self.int2bytes(4, self.total_procs)514 byte_stream += self.int2bytes(4, self.total_irqs)515 byte_stream += self.int2bytes(4, self.total_periphs)516 byte_stream += self.str2bytes( 64, self.name)500 byte_stream += self.int2bytes(4, self.signature) 501 byte_stream += self.int2bytes(4, self.x_size) 502 byte_stream += self.int2bytes(4, self.y_size) 503 byte_stream += self.int2bytes(4, self.x_width) 504 byte_stream += self.int2bytes(4, self.y_width) 505 byte_stream += self.int2bytes(4, self.x_io) 506 byte_stream += self.int2bytes(4, self.y_io) 507 byte_stream += self.int2bytes(4, self.irq_per_proc) 508 byte_stream += self.int2bytes(4, self.use_ramdisk) 509 byte_stream += self.int2bytes(4, self.total_globals) 510 byte_stream += self.int2bytes(4, self.total_vspaces) 511 byte_stream += self.int2bytes(4, self.total_psegs) 512 byte_stream += self.int2bytes(4, self.total_vsegs) 513 byte_stream += self.int2bytes(4, self.total_threads) 514 byte_stream += self.int2bytes(4, self.total_procs) 515 byte_stream += self.int2bytes(4, self.total_irqs) 516 byte_stream += self.int2bytes(4, self.total_periphs) 517 byte_stream += self.str2bytes(256, self.name) 517 518 518 519 if ( verbose ): … … 531 532 print 'total_psegs = %d' % self.total_psegs 532 533 print 'total_vsegs = %d' % self.total_vsegs 533 print 'total_t asks = %d' % self.total_tasks534 print 'total_threads = %d' % self.total_threads 534 535 print 'total_procs = %d' % self.total_procs 535 536 print 'total_irqs = %d' % self.total_irqs … … 574 575 if ( verbose ): print '\n' 575 576 576 # t asks array577 # threads array 577 578 index = 0 578 579 for vspace in self.vspaces: 579 for t ask in vspace.tasks:580 byte_stream += t ask.cbin( self, verbose, index, vspace )580 for thread in vspace.threads: 581 byte_stream += thread.cbin( self, verbose, index, vspace ) 581 582 index += 1 582 583 … … 985 986 if ( (boot_stack_found == False) or (boot_stack_identity == False) ): 986 987 print '[genmap error] in giet_vsegs()' 987 print ' seg_boot_sta sk missing or not identity mapping'988 print ' seg_boot_stack missing or not identity mapping' 988 989 sys.exit() 989 990 … … 1926 1927 self.active = active # active at boot if true 1927 1928 self.vsegs = [] 1928 self.t asks= []1929 self.threads = [] 1929 1930 1930 1931 return … … 1936 1937 %(self.name , self.startname , self.active) 1937 1938 for vseg in self.vsegs: s += vseg.xml() 1938 for t ask in self.tasks: s += task.xml()1939 for thread in self.threads: s += thread.xml() 1939 1940 s += ' </vspace>\n' 1940 1941 … … 1965 1966 sys.exit(1) 1966 1967 1967 # compute first vseg and first t askglobal index1968 # compute first vseg and first thread global index 1968 1969 first_vseg_id = self.vsegs[0].index 1969 first_t ask_id = self.tasks[0].index1970 1971 # compute number of t asks and number of vsegs1970 first_thread_id = self.threads[0].index 1971 1972 # compute number of threads and number of vsegs 1972 1973 nb_vsegs = len( self.vsegs ) 1973 nb_t asks = len( self.tasks )1974 nb_threads = len( self.threads ) 1974 1975 1975 1976 byte_stream = bytearray() … … 1977 1978 byte_stream += mapping.int2bytes(4, vseg_start_id) # vseg start_vector 1978 1979 byte_stream += mapping.int2bytes(4, nb_vsegs) # number of vsegs 1979 byte_stream += mapping.int2bytes(4, nb_t asks) # number of tasks1980 byte_stream += mapping.int2bytes(4, nb_threads) # number of threads 1980 1981 byte_stream += mapping.int2bytes(4, first_vseg_id) # global index 1981 byte_stream += mapping.int2bytes(4, first_t ask_id) # global index1982 byte_stream += mapping.int2bytes(4, first_thread_id) # global index 1982 1983 byte_stream += mapping.int2bytes(4, self.active) # always active if non zero 1983 1984 … … 1985 1986 print 'start_id = %d' % vseg_start_id 1986 1987 print 'nb_vsegs = %d' % nb_vsegs 1987 print 'nb_t asks = %d' % nb_tasks1988 print 'nb_threads = %d' % nb_threads 1988 1989 print 'vseg_id = %d' % first_vseg_id 1989 print 't ask_id = %d' % first_task_id1990 print 'thread_id = %d' % first_thread_id 1990 1991 print 'active = %d' % self.active 1991 1992 … … 1993 1994 1994 1995 ################################################################################## 1995 class T ask( object ):1996 class Thread( object ): 1996 1997 ################################################################################## 1997 1998 def __init__( self, 1998 1999 name, 1999 trdid,2000 is_main, 2000 2001 x, 2001 2002 y, … … 2005 2006 startid ): 2006 2007 2007 self.index = 0 # global index value set by addT ask()2008 self.name = name # t skname2009 self. trdid = trdid # task index (unique invspace)2008 self.index = 0 # global index value set by addThread() 2009 self.name = name # thread name 2010 self.is_main = is_main # Boolean (one main per vspace) 2010 2011 self.x = x # cluster x coordinate 2011 2012 self.y = y # cluster y coordinate … … 2016 2017 return 2017 2018 2018 ###################################### 2019 def xml( self ): # xml for one t ask2020 2021 s = ' <t askname="%s"' % self.name2022 s += ' trdid="%d"' % self.trdid2019 ######################################## 2020 def xml( self ): # xml for one thread 2021 2022 s = ' <thread name="%s"' % self.name 2023 s += ' is_main="%d"' % self.is_main 2023 2024 s += ' x="%d"' % self.x 2024 2025 s += ' y="%d"' % self.y … … 2032 2033 return s 2033 2034 2034 ########################################################################## 2035 def cbin( self, mapping, verbose, expected, vspace ): # C binary for T ask2035 ############################################################################ 2036 def cbin( self, mapping, verbose, expected, vspace ): # C binary for Thread 2036 2037 2037 2038 if ( verbose ): 2038 print '*** cbin for t ask%s in vspace %s' \2039 print '*** cbin for thread %s in vspace %s' \ 2039 2040 % (self.name, vspace.name) 2040 2041 2041 2042 # check index 2042 2043 if (self.index != expected): 2043 print '[genmap error] in T ask.cbin()'2044 print ' t askglobal index = %d / expected = %d' \2044 print '[genmap error] in Thread.cbin()' 2045 print ' thread global index = %d / expected = %d' \ 2045 2046 %(self.index,expected) 2046 2047 sys.exit(1) … … 2055 2056 2056 2057 if ( vseg_stack_id == 0xFFFFFFFF ): 2057 print '[genmap error] in T ask.cbin()'2058 print ' stackname %s not found for t ask%s in vspace %s' \2058 print '[genmap error] in Thread.cbin()' 2059 print ' stackname %s not found for thread %s in vspace %s' \ 2059 2060 % ( self.stackname, self.name, vspace.name ) 2060 2061 sys.exit(1) … … 2069 2070 2070 2071 if ( vseg_heap_id == 0xFFFFFFFF ): 2071 print '[genmap error] in T ask.cbin()'2072 print ' heapname %s not found for t ask%s in vspace %s' \2072 print '[genmap error] in Thread.cbin()' 2073 print ' heapname %s not found for thread %s in vspace %s' \ 2073 2074 % ( self.heapname, self.name, vspace.name ) 2074 2075 sys.exit(1) 2075 2076 2076 2077 byte_stream = bytearray() 2077 byte_stream += mapping.str2bytes(32,self.name) # t askname in vspace2078 byte_stream += mapping.str2bytes(32,self.name) # thread name in vspace 2078 2079 byte_stream += mapping.int2bytes(4, cluster_id) # cluster global index 2079 2080 byte_stream += mapping.int2bytes(4, self.p) # processor local index 2080 byte_stream += mapping.int2bytes(4, self. trdid) # thread index in vspace2081 byte_stream += mapping.int2bytes(4, self.is_main) # main if non zero 2081 2082 byte_stream += mapping.int2bytes(4, vseg_stack_id) # stack vseg local index 2082 2083 byte_stream += mapping.int2bytes(4, vseg_heap_id) # heap vseg local index … … 2087 2088 print 'clusterid = %d' % cluster_id 2088 2089 print 'lpid = %d' % self.p 2089 print ' trdid = %d' % self.trdid2090 print 'is_main = %d' % self.is_main 2090 2091 print 'stackid = %d' % vseg_stack_id 2091 2092 print 'heapid = %d' % vseg_heap_id -
soft/giet_vm/giet_xml/mapping_info.h
r645 r709 14 14 // 15 15 // 2/ a description of the applications (called vspaces) to be - statically - 16 // launched on the platform. The number of parallel tasks per application is16 // mapped on the platform. The number of parallel threads per application is 17 17 // variable (can be one). Each vspace contains a variable number 18 18 // of virtual segments (called vsegs). 19 19 // 20 // 3/ the mapping directives: both t asks on processors, and software objects21 // (vsegs) on thephysical memory banks (psegs).20 // 3/ the mapping directives: both threads on processors, and software objects 21 // (vsegs) on physical memory banks (psegs). 22 22 // 23 23 // The mapping_info data structure is organised as the concatenation of … … 28 28 // - mapping_vspace_t vspace[] 29 29 // - mapping_vseg_t vseg[] 30 // - mapping_t ask_t task[]30 // - mapping_thread_t thread[] 31 31 // - mapping_proc_t proc[] 32 32 // - mapping_irq_t irq[] … … 44 44 #define MAPPING_VSEG_SIZE sizeof(mapping_vseg_t) 45 45 #define MAPPING_PSEG_SIZE sizeof(mapping_pseg_t) 46 #define MAPPING_T ASK_SIZE sizeof(mapping_task_t)46 #define MAPPING_THREAD_SIZE sizeof(mapping_thread_t) 47 47 #define MAPPING_PROC_SIZE sizeof(mapping_proc_t) 48 48 #define MAPPING_IRQ_SIZE sizeof(mapping_irq_t) … … 152 152 unsigned int psegs; // total number of physical segments 153 153 unsigned int vsegs; // total number of virtual segments 154 unsigned int t asks; // total number of tasks154 unsigned int threads; // total number of threads 155 155 unsigned int procs; // total number of processors 156 156 unsigned int irqs; // total number of irqs 157 157 unsigned int periphs; // total number of peripherals 158 char name[ 64];// mapping name158 char name[256]; // mapping name 159 159 } mapping_header_t; 160 160 … … 183 183 unsigned int start_vseg_id; // vseg containing start vector index 184 184 unsigned int vsegs; // number of vsegs in vspace 185 unsigned int t asks; // number of tasks in vspace185 unsigned int threads; // number of threads in vspace 186 186 unsigned int vseg_offset; // global index of first vseg in vspace 187 unsigned int t ask_offset; // global index of first taskin vspace187 unsigned int thread_offset; // global index of first thread in vspace 188 188 unsigned int active; // always active if non zero 189 189 } mapping_vspace_t; … … 220 220 221 221 222 ////////////////////////////////////////////////////// 223 typedef struct __attribute__((packed)) mapping_t ask_s224 { 225 char name[32]; // t askname (unique in vspace)222 //////////////////////////////////////////////////////// 223 typedef struct __attribute__((packed)) mapping_thread_s 224 { 225 char name[32]; // thread name (unique in vspace) 226 226 unsigned int clusterid; // global index in clusters set 227 227 unsigned int proclocid; // processor local index (inside cluster) 228 unsigned int trdid; // thread index in vspace228 unsigned int is_main; // this thread is the application entry point 229 229 unsigned int stack_vseg_id; // global index for vseg containing stack 230 230 unsigned int heap_vseg_id; // global index for vseg containing heap 231 231 unsigned int startid; // index in start_vector 232 unsigned int ltid; // t askindex in scheduler (dynamically defined)233 } mapping_t ask_t;232 unsigned int ltid; // thread index in scheduler (dynamically defined) 233 } mapping_thread_t; 234 234 235 235 -
soft/giet_vm/giet_xml/xml_driver.c
r645 r709 126 126 unsigned int pseg_id; 127 127 unsigned int vseg_id; 128 unsigned int t ask_id;128 unsigned int thread_id; 129 129 unsigned int proc_id; 130 130 unsigned int irq_id; … … 135 135 mapping_vspace_t * vspace; 136 136 mapping_vseg_t * vseg; 137 mapping_t ask_t * task;137 mapping_thread_t * thread; 138 138 mapping_irq_t * irq; 139 139 mapping_periph_t * periph; … … 161 161 MAPPING_VSPACE_SIZE * header->vspaces); 162 162 163 // computes the base address for t asks array164 t ask = (mapping_task_t *) ((char *) header +163 // computes the base address for threads array 164 thread = (mapping_thread_t *) ((char *) header + 165 165 MAPPING_HEADER_SIZE + 166 166 MAPPING_CLUSTER_SIZE * header->x_size * header->y_size + … … 176 176 MAPPING_VSPACE_SIZE * header->vspaces + 177 177 MAPPING_VSEG_SIZE * header->vsegs + 178 MAPPING_T ASK_SIZE * header->tasks +178 MAPPING_THREAD_SIZE * header->threads + 179 179 MAPPING_PROC_SIZE * header->procs); 180 180 … … 186 186 MAPPING_VSPACE_SIZE * header->vspaces + 187 187 MAPPING_VSEG_SIZE * header->vsegs + 188 MAPPING_T ASK_SIZE * header->tasks +188 MAPPING_THREAD_SIZE * header->threads + 189 189 MAPPING_PROC_SIZE * header->procs + 190 190 MAPPING_IRQ_SIZE * header->irqs); … … 342 342 } 343 343 344 //////////////////// t asks //////////////////////////////////////////////345 346 for (t ask_id = vspace[vspace_id].task_offset;347 t ask_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);348 t ask_id++)344 //////////////////// threads ////////////////////////////////////////////// 345 346 for (thread_id = vspace[vspace_id].thread_offset; 347 thread_id < (vspace[vspace_id].thread_offset + vspace[vspace_id].threads); 348 thread_id++) 349 349 { 350 unsigned int stack_vseg_id = t ask[task_id].stack_vseg_id;351 unsigned int heap_vseg_id = t ask[task_id].heap_vseg_id;352 unsigned int cluster_id = t ask[task_id].clusterid;353 354 fprintf(fpout, " <t ask name=\"%s\"", task[task_id].name);355 fprintf(fpout, " trdid=\"%d\"", t ask[task_id].trdid);350 unsigned int stack_vseg_id = thread[thread_id].stack_vseg_id; 351 unsigned int heap_vseg_id = thread[thread_id].heap_vseg_id; 352 unsigned int cluster_id = thread[thread_id].clusterid; 353 354 fprintf(fpout, " <thread name=\"%s\"", thread[thread_id].name); 355 fprintf(fpout, " trdid=\"%d\"", thread[thread_id].trdid); 356 356 fprintf(fpout, " x=\"%d\"", cluster[cluster_id].x); 357 357 fprintf(fpout, " y=\"%d\"", cluster[cluster_id].y); 358 fprintf(fpout, " p=\"%d\"", t ask[task_id].proclocid);358 fprintf(fpout, " p=\"%d\"", thread[thread_id].proclocid); 359 359 fprintf(fpout, "\n "); 360 360 fprintf(fpout, " stackname=\"%s\"", vseg[stack_vseg_id].name); 361 361 if (heap_vseg_id != -1) 362 362 fprintf(fpout, " heapname=\"%s\"", vseg[heap_vseg_id].name); 363 fprintf(fpout, " startid = \"%d\"", t ask[task_id].startid);363 fprintf(fpout, " startid = \"%d\"", thread[thread_id].startid); 364 364 fprintf(fpout, " />\n"); 365 365 } -
soft/giet_vm/giet_xml/xml_parser.c
r645 r709 11 11 // 1) the multi-cluster/multi-processors hardware architecture description 12 12 // 2) the various multi-threaded software applications 13 // 3) the mapping directives bor both the t asks and the virtual segments.13 // 3) the mapping directives bor both the threads and the virtual segments. 14 14 // The corresponding C structures are defined in the "mapping_info.h" file. 15 15 /////////////////////////////////////////////////////////////////////////////////////// … … 31 31 #define MAX_PSEGS 4096 32 32 #define MAX_VSPACES 1024 33 #define MAX_T ASKS 409633 #define MAX_THREADS 4096 34 34 #define MAX_VSEGS 4096 35 35 #define MAX_PROCS 1024 … … 48 48 mapping_vspace_t * vspace[MAX_VSPACES]; // vspace array 49 49 mapping_vseg_t * vseg[MAX_VSEGS]; // vseg array 50 mapping_t ask_t * task[MAX_TASKS]; // taskarray50 mapping_thread_t * thread[MAX_THREADS]; // thread array 51 51 mapping_proc_t * proc[MAX_PROCS]; // proc array 52 52 mapping_irq_t * irq[MAX_IRQS]; // irq array … … 72 72 unsigned int vseg_loc_index = 0; 73 73 74 unsigned int t ask_index = 0;75 unsigned int t ask_loc_index = 0;74 unsigned int thread_index = 0; 75 unsigned int thread_loc_index = 0; 76 76 77 77 … … 275 275 276 276 277 ////////////////////////////////////// 278 void t askNode(xmlTextReaderPtr reader)277 //////////////////////////////////////// 278 void threadNode(xmlTextReaderPtr reader) 279 279 { 280 280 unsigned int ok; … … 285 285 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return; 286 286 287 if (t ask_index >= MAX_TASKS)288 { 289 printf("[XML ERROR] The number of t asks is larger than %d\n", MAX_TASKS);290 exit(1); 291 } 292 293 #if XML_PARSER_DEBUG 294 printf(" t ask %d\n", task_loc_index);295 #endif 296 297 t ask[task_index] = (mapping_task_t *) malloc(sizeof(mapping_task_t));287 if (thread_index >= MAX_THREADS) 288 { 289 printf("[XML ERROR] The number of threads is larger than %d\n", MAX_THREADS); 290 exit(1); 291 } 292 293 #if XML_PARSER_DEBUG 294 printf(" thread %d\n", thread_loc_index); 295 #endif 296 297 thread[thread_index] = (mapping_thread_t *) malloc(sizeof(mapping_thread_t)); 298 298 299 299 ////////// get name attribute … … 304 304 printf(" name = %s\n", str); 305 305 #endif 306 strncpy( task[task_index]->name, str, 31 ); 307 } 308 else 309 { 310 printf("[XML ERROR] illegal or missing <name> attribute for task (%d,%d)\n", 311 vspace_index, task_loc_index); 312 exit(1); 313 } 314 315 ///////// get trdid attribute (optional) 316 value = getIntValue(reader, "trdid", &ok); 317 #if XML_PARSER_DEBUG 318 printf(" trdid = %d\n", value ); 319 #endif 320 if ( ok ) task[task_index]->trdid = value; 321 else task[task_index]->trdid = task_loc_index; 306 strncpy( thread[thread_index]->name, str, 31 ); 307 } 308 else 309 { 310 printf("[XML ERROR] illegal or missing <name> for thread %d in vspace %d\n", 311 thread_loc_index, vspace_index); 312 exit(1); 313 } 314 315 ///////// get is_main attribute 316 value = getIntValue(reader, "is_main", &ok); 317 if ( ok ) 318 { 319 #if XML_PARSER_DEBUG 320 printf(" is_main = %d\n", value ); 321 #endif 322 thread[thread_index]->is_main = value; 323 } 324 else 325 { 326 printf("[XML ERROR] illegal or missing <is_main> for thread %d in vspace %d\n", 327 thread_loc_index, vspace_index); 328 } 322 329 323 330 ///////// get x coordinate … … 328 335 if ( !(ok && (x < header->x_size)) ) 329 336 { 330 printf("[XML ERROR] illegal or missing < x > attribute for task (%d,%d)\n",331 vspace_index, task_loc_index);337 printf("[XML ERROR] illegal or missing < x > for thread %d in vspace %d)\n", 338 thread_loc_index, vspace_index); 332 339 exit(1); 333 340 } … … 340 347 if ( !(ok && (y < header->y_size)) ) 341 348 { 342 printf("[XML ERROR] illegal or missing < y > attribute for task (%d,%d)\n",343 vspace_index, task_loc_index);349 printf("[XML ERROR] illegal or missing < y > for thread %d in vspace %d)\n", 350 thread_loc_index, vspace_index); 344 351 exit(1); 345 352 } … … 352 359 if( index >= 0 ) 353 360 { 354 t ask[task_index]->clusterid = index;361 thread[thread_index]->clusterid = index; 355 362 } 356 363 else 357 364 { 358 printf("[XML ERROR] <clusterid> not found for t ask (%d,%d)\n",359 vspace_index, task_loc_index);365 printf("[XML ERROR] <clusterid> not found for thread %d in vspace %d)\n", 366 thread_loc_index, vspace_index); 360 367 exit(1); 361 368 } … … 368 375 printf(" proclocid = %x\n", value); 369 376 #endif 370 if (value >= cluster[t ask[task_index]->clusterid]->procs)371 { 372 printf("[XML ERROR] <proclocid> too large for t ask (%d,%d)\n",373 vspace_index, task_loc_index);377 if (value >= cluster[thread[thread_index]->clusterid]->procs) 378 { 379 printf("[XML ERROR] <proclocid> too large for thread %d in vspace %d\n", 380 thread_loc_index, vspace_index); 374 381 exit(1); 375 382 } 376 t ask[task_index]->proclocid = value;383 thread[thread_index]->proclocid = value; 377 384 } 378 385 else 379 386 { 380 printf("[XML ERROR] illegal or missing < p> attribute for task (%d,%d)\n",381 vspace_index, task_loc_index);387 printf("[XML ERROR] illegal or missing < p > for thread %d in vspace %d)\n", 388 thread_loc_index, vspace_index); 382 389 exit(1); 383 390 } … … 396 403 printf(" stack_id = %d\n", index); 397 404 #endif 398 t ask[task_index]->stack_vseg_id = index;405 thread[thread_index]->stack_vseg_id = index; 399 406 } 400 407 else 401 408 { 402 printf("[XML ERROR] illegal or missing <stackname> for t ask (%d,%d)\n",403 vspace_index, task_loc_index);409 printf("[XML ERROR] illegal or missing <stackname> for thread %d in vspace %d)\n", 410 thread_loc_index, vspace_index); 404 411 exit(1); 405 412 } … … 407 414 else 408 415 { 409 printf("[XML ERROR] illegal or missing <stackname> for t ask (%d,%d)\n",410 vspace_index, task_loc_index);416 printf("[XML ERROR] illegal or missing <stackname> for thread %d in vspace %d)\n", 417 thread_loc_index, vspace_index); 411 418 exit(1); 412 419 } … … 425 432 printf(" heap_id = %d\n", index ); 426 433 #endif 427 t ask[task_index]->heap_vseg_id = index;434 thread[thread_index]->heap_vseg_id = index; 428 435 } 429 436 else 430 437 { 431 printf("[XML ERROR] illegal or missing <heapname> for t ask (%d,%d)\n",432 vspace_index, task_loc_index);438 printf("[XML ERROR] illegal or missing <heapname> for thread %d in vspace %d)\n", 439 thread_loc_index, vspace_index); 433 440 exit(1); 434 441 } … … 436 443 else 437 444 { 438 t ask[task_index]->heap_vseg_id = -1;445 thread[thread_index]->heap_vseg_id = -1; 439 446 } 440 447 … … 446 453 printf(" startid = %x\n", value); 447 454 #endif 448 t ask[task_index]->startid = value;455 thread[thread_index]->startid = value; 449 456 } 450 457 else 451 458 { 452 printf("[XML ERROR] illegal or missing <startid> attribute for task (%d,%d)\n",453 vspace_index, task_loc_index);454 exit(1); 455 } 456 457 t ask_index++;458 t ask_loc_index++;459 } // end t askNode()459 printf("[XML ERROR] illegal or missing <startid> for thread %d in vspace %d\n", 460 thread_loc_index, vspace_index); 461 exit(1); 462 } 463 464 thread_index++; 465 thread_loc_index++; 466 } // end threadNode() 460 467 461 468 … … 698 705 unsigned int ok; 699 706 700 vseg_loc_index = 0;701 t ask_loc_index = 0;707 vseg_loc_index = 0; 708 thread_loc_index = 0; 702 709 703 710 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return; … … 727 734 else vspace[vspace_index]->active = 0; 728 735 729 ////////// set vseg_offset and t ask_offset attributes736 ////////// set vseg_offset and thread_offset attributes 730 737 vspace[vspace_index]->vseg_offset = vseg_index; 731 vspace[vspace_index]->t ask_offset = task_index;732 733 ////////// initialise vsegs and t asks attributes738 vspace[vspace_index]->thread_offset = thread_index; 739 740 ////////// initialise vsegs and threads attributes 734 741 vspace[vspace_index]->vsegs = 0; 735 vspace[vspace_index]->t asks = 0;742 vspace[vspace_index]->threads = 0; 736 743 737 744 ////////// get startname attribute … … 754 761 vspace[vspace_index]->vsegs += 1; 755 762 } 756 else if (strcmp(tag, "t ask") == 0)757 { 758 t askNode(reader);759 vspace[vspace_index]->t asks += 1;763 else if (strcmp(tag, "thread") == 0) 764 { 765 threadNode(reader); 766 vspace[vspace_index]->threads += 1; 760 767 } 761 768 else if (strcmp(tag, "#text") == 0) { } … … 777 784 778 785 #if XML_PARSER_DEBUG 779 printf(" vsegs = %d\n", vspace[vspace_index]->vsegs );780 printf(" t asks = %d\n", vspace[vspace_index]->tasks );781 printf(" vseg_offset = %d\n", vspace[vspace_index]->vseg_offset );782 printf(" t ask_offset = %d\n", vspace[vspace_index]->task_offset );783 printf(" start_id = %d\n", vspace[vspace_index]->start_vseg_id );784 printf(" active = %x\n", vspace[vspace_index]->active );786 printf(" vsegs = %d\n", vspace[vspace_index]->vsegs ); 787 printf(" threads = %d\n", vspace[vspace_index]->threads ); 788 printf(" vseg_offset = %d\n", vspace[vspace_index]->vseg_offset ); 789 printf(" thread_offset = %d\n", vspace[vspace_index]->thread_offset ); 790 printf(" start_id = %d\n", vspace[vspace_index]->start_vseg_id ); 791 printf(" active = %x\n", vspace[vspace_index]->active ); 785 792 printf(" end vspace %d\n\n", vspace_index); 786 793 #endif … … 1488 1495 { 1489 1496 header->vsegs = vseg_index; 1490 header->t asks = task_index;1497 header->threads = thread_index; 1491 1498 return; 1492 1499 } … … 1668 1675 header->psegs = 0; 1669 1676 header->vsegs = 0; 1670 header->t asks= 0;1677 header->threads = 0; 1671 1678 header->procs = 0; 1672 1679 header->irqs = 0; … … 1765 1772 printf("psegs = %d\n", header->psegs); 1766 1773 printf("vsegs = %d\n", header->vsegs); 1767 printf("t asks = %d\n", header->tasks);1774 printf("threads = %d\n", header->threads); 1768 1775 printf("procs = %d\n", header->procs); 1769 1776 printf("irqs = %d\n", header->irqs); … … 1787 1794 // write vsegs 1788 1795 BuildTable(fdout, "vseg", vseg_index, sizeof(mapping_vseg_t), (char **) vseg); 1789 // write t asks array1790 BuildTable(fdout, "t ask", task_index, sizeof(mapping_task_t), (char **) task);1796 // write threads array 1797 BuildTable(fdout, "thread", thread_index, sizeof(mapping_thread_t), (char **) thread); 1791 1798 //building procs array 1792 1799 BuildTable(fdout, "proc", proc_index, sizeof(mapping_proc_t), (char **) proc);
Note: See TracChangeset
for help on using the changeset viewer.