Changeset 709 for soft/giet_vm/giet_kernel
- Timestamp:
- Oct 1, 2015, 4:20:46 PM (9 years ago)
- Location:
- soft/giet_vm/giet_kernel
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note: See TracChangeset
for help on using the changeset viewer.