Changeset 407 for trunk/kernel
- Timestamp:
- Nov 7, 2017, 3:08:12 PM (7 years ago)
- Location:
- trunk/kernel
- Files:
-
- 2 deleted
- 79 edited
- 4 copied
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/devices/dev_dma.c
r406 r407 88 88 thread_t * this = CURRENT_THREAD; 89 89 90 dma_dmsg("\n[D MSG] %s : enters for thread %x / dst = %l /src = %l / size = %x\n",90 dma_dmsg("\n[DBG] %s : enters for thread %x / dst = %l /src = %l / size = %x\n", 91 91 __FUNCTION__ , this->trdid , dst_xp , src_xp , size ); 92 92 … … 108 108 // block client thread on THREAD_BLOCKED_IO and deschedule. 109 109 // it is re-activated by the ISR signaling IO operation completion. 110 chdev_register_command( dev_xp , this);110 chdev_register_command( dev_xp ); 111 111 112 dma_dmsg("\n[D MSG] %s : completes for thread %x / error = %d\n",112 dma_dmsg("\n[DBG] %s : completes for thread %x / error = %d\n", 113 113 __FUNCTION__ , this->trdid , this->dma_cmd.error ); 114 114 -
trunk/kernel/devices/dev_fbf.c
r406 r407 143 143 } 144 144 145 fbf_dmsg("\n[D MSG] %s : thread %x in process %x / vaddr = %p / paddr = %l\n",145 fbf_dmsg("\n[DBG] %s : thread %x in process %x / vaddr = %p / paddr = %l\n", 146 146 __FUNCTION__ , this->trdid , this->process->pid , buffer , buf_paddr ); 147 147 -
trunk/kernel/devices/dev_ioc.c
r406 r407 51 51 52 52 // set chdev name 53 snprintf( ioc->name , 16 , "ioc _%d" , channel );53 snprintf( ioc->name , 16 , "ioc%d" , channel ); 54 54 55 55 // call driver init function … … 90 90 // It builds and registers the command in the calling thread descriptor. 91 91 // Then, it registers the calling thead in chdev waiting queue. 92 // Finally it blocks on the THREAD_BLOCKED_ DEVcondition and deschedule.92 // Finally it blocks on the THREAD_BLOCKED_IO condition and deschedule. 93 93 ////////////////////////////////////i///////////////////////////////////////////// 94 94 static error_t dev_ioc_access( uint32_t cmd_type, … … 99 99 thread_t * this = CURRENT_THREAD; // pointer on client thread 100 100 101 ioc_dmsg("\n[D MSG] %s : thread %x in process %x"101 ioc_dmsg("\n[DBG] %s : thread %x in process %x" 102 102 " for lba = %x / buffer = %x / at cycle %d\n", 103 103 __FUNCTION__ , this->trdid , this->process->pid , … … 126 126 // block client thread on THREAD_BLOCKED_IO and deschedule. 127 127 // it is re-activated by the ISR signaling IO operation completion. 128 chdev_register_command( dev_xp , this);129 130 ioc_dmsg("\n[D MSG] in %s : thread %x in process %x"128 chdev_register_command( dev_xp ); 129 130 ioc_dmsg("\n[DBG] in %s : thread %x in process %x" 131 131 " completes / error = %d / at cycle %d\n", 132 132 __FUNCTION__ , this->trdid , this->process->pid , … … 162 162 thread_t * this = CURRENT_THREAD; 163 163 164 ioc_dmsg("\n[D MSG] %s : core[%x,%d] enter for %d blocks / lba = %x / cycle %d\n",164 ioc_dmsg("\n[DBG] %s : core[%x,%d] enter for %d blocks / lba = %x / cycle %d\n", 165 165 __FUNCTION__ , local_cxy , this->core->lid , count , lba , hal_time_stamp() ); 166 166 … … 199 199 dev_pic_enable_irq( lid , ioc_xp ); 200 200 201 ioc_dmsg("\n[D MSG] %s : core[%x,%d] exit / error = %d / cycle %d\n",201 ioc_dmsg("\n[DBG] %s : core[%x,%d] exit / error = %d / cycle %d\n", 202 202 __FUNCTION__ , local_cxy , this->core->lid , this->ioc_cmd.error , hal_time_stamp() ); 203 203 -
trunk/kernel/devices/dev_mmc.c
r406 r407 99 99 thread_t * this = CURRENT_THREAD; 100 100 101 mmc_dmsg("\n[D MSG] %s enters for thread %x in process %x / buf_xp = %l\n",101 mmc_dmsg("\n[DBG] %s enters for thread %x in process %x / buf_xp = %l\n", 102 102 __FUNCTION__ , this->trdid , this->process->pid , buf_xp ); 103 103 … … 124 124 error = dev_mmc_access( this ); 125 125 126 mmc_dmsg("\n[D MSG] %s completes for thread %x in process %x / error = %d\n",126 mmc_dmsg("\n[DBG] %s completes for thread %x in process %x / error = %d\n", 127 127 __FUNCTION__ , this->trdid , this->process->pid , error ); 128 128 … … 139 139 thread_t * this = CURRENT_THREAD; 140 140 141 mmc_dmsg("\n[D MSG] %s enters for thread %x in process %x / buf_xp = %l\n",141 mmc_dmsg("\n[DBG] %s enters for thread %x in process %x / buf_xp = %l\n", 142 142 __FUNCTION__ , this->trdid , this->process->pid , buf_xp ); 143 143 … … 164 164 error = dev_mmc_access( this ); 165 165 166 mmc_dmsg("\n[D MSG] %s completes for thread %x in process %x / error = %d\n",166 mmc_dmsg("\n[DBG] %s completes for thread %x in process %x / error = %d\n", 167 167 __FUNCTION__ , this->trdid , this->process->pid , error ); 168 168 -
trunk/kernel/devices/dev_nic.c
r406 r407 51 51 52 52 // set chdev name 53 if( is_rx ) snprintf( nic->name , 16 , "nic _rx_%d" , channel );54 else snprintf( nic->name , 16 , "nic _tx_%d" , channel );53 if( is_rx ) snprintf( nic->name , 16 , "nic%d_rx" , channel ); 54 else snprintf( nic->name , 16 , "nic%d_tx" , channel ); 55 55 56 56 // call driver init function … … 97 97 core_t * core = thread_ptr->core; 98 98 99 nic_dmsg("\n[D MSG] %s enters for NIC-RX thread on core %d in cluster %x\n",99 nic_dmsg("\n[DBG] %s enters for NIC-RX thread on core %d in cluster %x\n", 100 100 __FUNCTION__ , core->lid , local_cxy ); 101 101 … … 129 129 // block on THREAD_BLOCKED_IO condition and deschedule 130 130 thread_block( thread_ptr , THREAD_BLOCKED_IO ); 131 sched_yield( NULL);131 sched_yield(); 132 132 133 133 // disable NIC-RX IRQ … … 147 147 pkd->length = thread_ptr->nic_cmd.length; 148 148 149 nic_dmsg("\n[D MSG] %s exit for NIC-RX thread on core %d in cluster %x\n",149 nic_dmsg("\n[DBG] %s exit for NIC-RX thread on core %d in cluster %x\n", 150 150 __FUNCTION__ , core->lid , local_cxy ); 151 151 … … 167 167 core_t * core = thread_ptr->core; 168 168 169 nic_dmsg("\n[D MSG] %s enters for NIC-RX thread on core %d in cluster %x\n",169 nic_dmsg("\n[DBG] %s enters for NIC-RX thread on core %d in cluster %x\n", 170 170 __FUNCTION__ , core->lid , local_cxy ); 171 171 … … 199 199 // block on THREAD_BLOCKED I/O condition and deschedule 200 200 thread_block( thread_ptr , THREAD_BLOCKED_IO ); 201 sched_yield( NULL);201 sched_yield(); 202 202 203 203 // disable NIC-TX IRQ … … 215 215 if( error ) return error; 216 216 217 nic_dmsg("\n[D MSG] %s exit for NIC-TX thread on core %d in cluster %x\n",217 nic_dmsg("\n[DBG] %s exit for NIC-TX thread on core %d in cluster %x\n", 218 218 __FUNCTION__ , core->lid , local_cxy ); 219 219 -
trunk/kernel/devices/dev_nic.h
r14 r407 107 107 enum nic_impl_e 108 108 { 109 IMPL_NIC_ SOC= 0,109 IMPL_NIC_CBF = 0, 110 110 IMPL_NIC_I86 = 1, 111 111 } -
trunk/kernel/devices/dev_pic.c
r406 r407 36 36 37 37 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 38 extern iopic_input_t iopic_input; // allocated in kernel_init.c 38 39 39 40 /////////////////////////////////// … … 83 84 xptr_t src_chdev_xp ) 84 85 { 85 irq_dmsg("\n[DMSG] %s : core = [%x,%d] / src_chdev_cxy = %x / src_chdev_ptr = %x\n", 86 __FUNCTION__ , local_cxy , lid , GET_CXY(src_chdev_xp) , GET_PTR(src_chdev_xp) ); 86 87 irq_dmsg("\n[DBG] %s : core = [%x,%d] / src_chdev_cxy = %x / src_chdev_ptr = %x\n", 88 __FUNCTION__ , local_cxy , lid , GET_CXY(src_chdev_xp) , GET_PTR(src_chdev_xp) ); 87 89 88 90 // get pointer on PIC chdev … … 101 103 xptr_t src_chdev_xp ) 102 104 { 103 irq_dmsg("\n[DMSG] %s : core = [%x,%d] / src_chdev_cxy = %x / src_chdev_ptr = %x\n", 104 __FUNCTION__ , local_cxy , lid , GET_CXY(src_chdev_xp) , GET_PTR(src_chdev_xp) ); 105 106 irq_dmsg("\n[DBG] %s : core = [%x,%d] / src_chdev_cxy = %x / src_chdev_ptr = %x\n", 107 __FUNCTION__ , local_cxy , lid , GET_CXY(src_chdev_xp) , GET_PTR(src_chdev_xp) ); 105 108 106 109 // get pointer on PIC chdev … … 118 121 void dev_pic_enable_timer( uint32_t period ) 119 122 { 120 irq_dmsg("\n[DMSG] %s : core = [%x,%d] / period = %d\n", 121 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , period ); 123 124 irq_dmsg("\n[DBG] %s : core = [%x,%d] / period = %d\n", 125 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , period ); 122 126 123 127 // get pointer on PIC chdev … … 135 139 void dev_pic_enable_ipi() 136 140 { 137 irq_dmsg("\n[DMSG] %s : core = [%x,%d]\n", 138 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid ); 141 142 irq_dmsg("\n[DBG] %s : core = [%x,%d] / cycle %d\n", 143 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() ); 139 144 140 145 // get pointer on PIC chdev … … 153 158 lid_t lid ) 154 159 { 155 irq_dmsg("\n[DMSG] %s : enter / src_core = [%x,%d] / dst_core = [%x,%d] / cycle %d\n", 156 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, cxy, lid, hal_time_stamp() ); 160 161 irq_dmsg("\n[DBG] %s : src_core = [%x,%d] / dst_core = [%x,%d] / cycle %d\n", 162 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, cxy, lid, hal_time_stamp() ); 157 163 158 164 // get pointer on PIC chdev … … 165 171 // call relevant driver function 166 172 f( cxy , lid ); 167 168 irq_dmsg("\n[DMSG] %s : exit / src_core = [%x,%d] / dst_core = [%x,%d] / cycle %d\n", 169 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, cxy, lid, hal_time_stamp() ); 170 } 171 173 } 174 175 ////////////////////// 176 void dev_pic_ack_ipi() 177 { 178 179 irq_dmsg("\n[DBG] %s : core = [%x,%d] / cycle %d\n", 180 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, hal_time_stamp() ); 181 182 // get pointer on PIC chdev 183 chdev_t * pic_ptr = (chdev_t *)GET_PTR( chdev_dir.pic ); 184 cxy_t pic_cxy = GET_CXY( chdev_dir.pic ); 185 186 // get pointer on ack_ipi function 187 ack_ipi_t * f = hal_remote_lpt( XPTR( pic_cxy , &pic_ptr->ext.pic.ack_ipi ) ); 188 189 // call relevant driver function 190 f(); 191 } 192 193 ///////////////////////////// 194 void dev_pic_inputs_display() 195 { 196 uint32_t k; 197 uint32_t save_sr; 198 199 // get pointers on TXT0 chdev 200 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 201 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 202 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 203 204 // get extended pointer on remote TXT0 chdev lock 205 xptr_t lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 206 207 // get TXT0 lock in busy waiting mode 208 remote_spinlock_lock_busy( lock_xp , &save_sr ); 209 210 nolock_printk("\n***** iopic_inputs\n"); 211 212 for( k = 0 ; k < CONFIG_MAX_IOC_CHANNELS ; k++ ) 213 { 214 nolock_printk(" - IOC[%d] hwi_id = %d\n", k , iopic_input.ioc[k] ); 215 } 216 217 for( k = 0 ; k < CONFIG_MAX_TXT_CHANNELS ; k++ ) 218 { 219 nolock_printk(" - TXT_TX[%d] hwi_id = %d\n", k , iopic_input.txt_tx[k] ); 220 nolock_printk(" - TXT_RX[%d] hwi_id = %d\n", k , iopic_input.txt_rx[k] ); 221 } 222 223 for( k = 0 ; k < CONFIG_MAX_NIC_CHANNELS ; k++ ) 224 { 225 nolock_printk(" - NIC_TX[%d] hwi_id = %d\n", k , iopic_input.nic_tx[k] ); 226 nolock_printk(" - NIC_RX[%d] hwi_id = %d\n", k , iopic_input.nic_rx[k] ); 227 } 228 229 // release TXT0 lock 230 remote_spinlock_unlock_busy( lock_xp , save_sr ); 231 } 232 233 -
trunk/kernel/devices/dev_pic.h
r406 r407 80 80 /***************************************************************************************** 81 81 * This defines the specific extension for the PIC chdev descriptor. 82 * It contains four function pointers on the four PIC command types,83 * that must be implemented by alldrivers.82 * It contains the function pointers for all functions that mus be implemented 83 * by all implementation specific drivers. 84 84 ****************************************************************************************/ 85 85 … … 90 90 typedef void (enable_ipi_t) ( ); 91 91 typedef void (send_ipi_t) ( cxy_t cxy , lid_t lid ); 92 typedef void (ack_ipi_t) ( ); 92 93 typedef void (extend_init_t) ( uint32_t * lapic_base ); 93 94 … … 98 99 disable_irq_t * disable_irq; /*! pointer on the driver "disable_irq" function */ 99 100 enable_timer_t * enable_timer; /*! pointer on the driver "enable_timer" function */ 100 enable_ timer_t* enable_ipi; /*! pointer on the driver "enable_ipi" function */101 enable_ipi_t * enable_ipi; /*! pointer on the driver "enable_ipi" function */ 101 102 send_ipi_t * send_ipi; /*! pointer on the driver "send_ipi" function */ 103 ack_ipi_t * ack_ipi; /*! pointer on the driver "ack_ipi" function */ 102 104 extend_init_t * extend_init; /*! pointer on the driver "init_extend" function */ 103 105 } … … 109 111 * It describes the hardware wiring of IRQs between external peripherals and the IOPIC, 110 112 * as each entry contains the input IRQ index in IOPIC. 111 * For a multi-channels peripheral, there is one chdev and one IRQ per channel.113 * For a multi-channels/multi_IRQ peripheral, there is one chdev per IRQ. 112 114 * This structure is replicated in each cluster. It is allocated as a global variable 113 115 * in the kernel_init.c file. … … 116 118 typedef struct iopic_input_s 117 119 { 118 uint32_t txt[CONFIG_MAX_TXT_CHANNELS];119 120 uint32_t ioc[CONFIG_MAX_IOC_CHANNELS]; 121 uint32_t txt_rx[CONFIG_MAX_TXT_CHANNELS]; 122 uint32_t txt_tx[CONFIG_MAX_TXT_CHANNELS]; 120 123 uint32_t nic_rx[CONFIG_MAX_NIC_CHANNELS]; 121 124 uint32_t nic_tx[CONFIG_MAX_NIC_CHANNELS]; … … 180 183 * This is a static binding, defined during kernel init: IRQ can be enabled/disabled, 181 184 * but the binding cannot be released. It can be used for both internal & external IRQs. 185 * The configuration is actually done by the - implementation specific - driver, 186 * and this function just call the relevant driver. 182 187 * WARNING : the IRQ must be explicitely enabled by the dev_pic_enable_irq() function. 183 188 ***************************************************************************************** … … 234 239 lid_t lid ); 235 240 241 /***************************************************************************************** 242 * This function acknowledges the IPI identified by the calling core local index, 243 * in the local LAPIC component. 244 ****************************************************************************************/ 245 void dev_pic_ack_ipi(); 246 247 /***************************************************************************************** 248 * This debug function displays the content of the iopic_input structure, 249 * that register the input IRQS for the external IOPIC controller. 250 ****************************************************************************************/ 251 void dev_pic_inputs_display(); 236 252 237 253 #endif /* _DEV_PIC_H_ */ -
trunk/kernel/devices/dev_txt.c
r406 r407 27 27 #include <hal_drivers.h> 28 28 #include <thread.h> 29 #include <chdev.h> 29 30 #include <rpc.h> 30 31 #include <printk.h> … … 36 37 37 38 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 39 40 #if CONFIG_READ_DEBUG 41 extern uint32_t enter_txt_read; 42 extern uint32_t exit_txt_read; 43 #endif 38 44 39 45 ////////////////////////////////// … … 47 53 uint32_t channel = txt->channel; 48 54 uint32_t impl = txt->impl; 55 bool_t is_rx = txt->is_rx; 49 56 50 57 assert( (pic_xp != XPTR_NULL) || (channel == 0) , __FUNCTION__ , … … 52 59 53 60 // set chdev name 54 snprintf( txt->name , 16 , "txt_%d" , channel ); 61 if( is_rx ) snprintf( txt->name , 16 , "txt%d_rx" , channel ); 62 else snprintf( txt->name , 16 , "txt%d_tx" , channel ); 55 63 56 64 // call driver init function … … 61 69 if( channel != 0 && impl != IMPL_TXT_RS2 ) 62 70 { 63 // select a core to execute the TXTserver thread71 // select a core to execute the server thread 64 72 lid_t lid = cluster_select_local_core(); 65 73 66 // bind TXTIRQ to the selected core74 // bind IRQ to the selected core 67 75 dev_pic_bind_irq( lid , txt ); 68 76 69 // enable TXTIRQ77 // enable IRQ 70 78 dev_pic_enable_irq( lid , XPTR( local_cxy , txt ) ); 71 79 … … 99 107 uint32_t count ) 100 108 { 109 xptr_t dev_xp; 101 110 thread_t * this = CURRENT_THREAD; 102 111 103 txt_dmsg("\n[DMSG] in %s : thread %x in process %x enters\n",104 __FUNCTION__ , this->trdid , this->process->pid);112 txt_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) enters / cycle %d\n", 113 __FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type), hal_time_stamp() ); 105 114 106 115 // check channel argument … … 108 117 109 118 // get extended pointer on remote TXT chdev descriptor 110 xptr_t dev_xp = chdev_dir.txt[channel]; 119 if( type == TXT_WRITE ) dev_xp = chdev_dir.txt_tx[channel]; 120 else dev_xp = chdev_dir.txt_rx[channel]; 111 121 112 122 assert( (dev_xp != XPTR_NULL) , __FUNCTION__ , "undefined TXT chdev descriptor" ); … … 121 131 // block client thread on THREAD_BLOCKED_IO and deschedule. 122 132 // it is re-activated by the ISR signaling IO operation completion. 123 chdev_register_command( dev_xp , this);133 chdev_register_command( dev_xp ); 124 134 125 txt_dmsg("\n[DMSG] in %s : thread %x in process %x completes / error =%d\n",126 __FUNCTION__ , this->trdid , this->process->pid , this->txt_cmd.error);135 txt_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) exit / cycle %d\n", 136 __FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type), hal_time_stamp() ); 127 137 128 138 // return I/O operation status from calling thread descriptor … … 135 145 uint32_t count ) 136 146 { 137 return dev_txt_access( TXT_WRITE , channel , buffer , count ); 147 error_t error = dev_txt_access( TXT_WRITE , channel , buffer , count ); 148 return error; 138 149 } 139 150 … … 142 153 char * buffer ) 143 154 { 144 return dev_txt_access( TXT_READ , channel , buffer , 1 ); 155 156 #if CONFIG_READ_DEBUG 157 enter_txt_read = hal_time_stamp(); 158 #endif 159 160 error_t error = dev_txt_access( TXT_READ , channel , buffer , 1 ); 161 162 #if CONFIG_READ_DEBUG 163 exit_txt_read = hal_time_stamp(); 164 #endif 165 166 return error; 167 145 168 } 146 169 147 /////////////////////////////////////////////// 148 error_t dev_txt_sync_write( uint32_t channel, 149 char * buffer, 170 ////////////////////////////////////////////// 171 error_t dev_txt_sync_write( char * buffer, 150 172 uint32_t count ) 151 173 { 152 // get pointer on calling thread153 thread_t * this = CURRENT_THREAD;174 // get extended pointer on TXT[0] chdev 175 xptr_t dev_xp = chdev_dir.txt_tx[0]; 154 176 155 // get extended pointer on TXT[0] chdev156 xptr_t dev_xp = chdev_dir.txt[channel];177 assert( (dev_xp != XPTR_NULL) , __FUNCTION__ , 178 "undefined TXT0 chdev descriptor" ); 157 179 158 assert( (dev_xp != XPTR_NULL) , __FUNCTION__ , "undefined TXT0 chdev descriptor" ); 159 160 // register command in calling thread descriptor 161 this->txt_cmd.dev_xp = dev_xp; 162 this->txt_cmd.type = TXT_SYNC_WRITE; 163 this->txt_cmd.buf_xp = XPTR( local_cxy , buffer ); 164 this->txt_cmd.count = count; 180 // get TXTO chdev cluster and local pointer 181 cxy_t dev_cxy = GET_CXY( dev_xp ); 182 chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp ); 165 183 166 184 // get driver command function 167 cxy_t dev_cxy = GET_CXY( dev_xp ); 168 chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp ); 169 dev_cmd_t * cmd = (dev_cmd_t *)hal_remote_lpt( XPTR( dev_cxy , &dev_ptr->cmd ) ); 185 dev_aux_t * aux = (dev_aux_t *)hal_remote_lpt( XPTR( dev_cxy , &dev_ptr->aux ) ); 186 187 // build arguments structure 188 txt_aux_t args; 189 args.dev_xp = dev_xp; 190 args.buffer = buffer; 191 args.count = count; 170 192 171 193 // call driver function 172 cmd( XPTR( local_cxy , this ));194 aux( &args ); 173 195 174 // return I/O operation status from calling thread descriptor 175 return this->txt_cmd.error; 196 return 0; 176 197 } 177 198 -
trunk/kernel/devices/dev_txt.h
r254 r407 36 36 * 37 37 * This multi-channels generic TXT device provides access to a text terminal. 38 * It supports three operation types : 38 * 39 * It supports two operations that must be implemented by the driver cmd() function: 39 40 * - TXT_READ : read a single character from the text terminal identified by its channel 40 41 * index, using a descheduling strategy for the calling thread. 41 42 * - TXT_WRITE : write a character string to the text terminal identified by its channel 42 43 * index, using a descheduling strategy for the calling thread. 43 * - TXT_SYNC_WRITE : write a character string to the terminal identified by its channel 44 * index, using a busy waiting strategy for the calling thread. 44 * 45 * It supports one operation, that must be implemented by the driver aux() function 46 * - TXT_SYNC_WRITE write a character string to the TXT0 kernel terminal, using a busy 47 * waiting strategy for the calling thread. 45 48 *****************************************************************************************/ 46 49 … … 58 61 59 62 /****************************************************************************************** 60 * This defines the (implementation independent) command passed to the driver.63 * This defines the arguments passed to the driver CMD function. 61 64 *****************************************************************************************/ 62 65 … … 65 68 TXT_READ = 0, 66 69 TXT_WRITE = 1, 67 TXT_SYNC_WRITE = 2,68 70 }; 69 71 … … 77 79 } 78 80 txt_command_t; 81 82 /****************************************************************************************** 83 * This defines the arguments passed to the driver AUX function. 84 * This function implement the TXT_SYNC_WRITE operation. 85 *****************************************************************************************/ 86 87 typedef struct txt_aux_s 88 { 89 xptr_t dev_xp; /*! extended pointer on the TXT0 device descriptor */ 90 char * buffer; /*! local pointer on characters array */ 91 uint32_t count; /*! number of characters in buffer */ 92 } 93 txt_aux_t; 79 94 80 95 /****************************************************************************************** … … 122 137 123 138 /*************************************************************************************** 124 * This low-level blocking function is used by the kernel to display one string on a 125 * given TXT channel without descheduling the calling thread, without registering it 126 * in the TXT device waiting queue, and without using the TXT irq. 139 * This blocking function is used by the kernel to display a string on the TXT0 140 * terminal, without descheduling the calling thread, without registering it 141 * in the TXT0 device waiting queue, without using the TXT0 irq, and without 142 * interfering with another possible TXT access to another terminal. 143 * As it is used for debug, the command arguments <buffer> and <count> are registerd 144 * in a specific "dbg_cmd" field of the calling thread. 145 * other TXT accesses. 127 146 **************************************************************************************** 128 * @ channel : TXT channel index.129 147 * @ buffer : local pointer on source buffer containing the string. 130 148 * @ count : number of characters. 131 149 * @ returns 0 if success / returns EINVAL if error. 132 150 ***************************************************************************************/ 133 error_t dev_txt_sync_write( uint32_t channel, 134 char * buffer, 151 error_t dev_txt_sync_write( char * buffer, 135 152 uint32_t count ); 136 153 -
trunk/kernel/fs/devfs.c
r406 r407 25 25 #include <hal_types.h> 26 26 #include <hal_special.h> 27 #include <hal_uspace.h> 27 28 #include <printk.h> 28 29 #include <chdev.h> 30 #include <dev_txt.h> 29 31 #include <cluster.h> 30 32 #include <vfs.h> … … 39 41 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 40 42 43 #if CONFIG_READ_DEBUG 44 extern uint32_t enter_devfs_move; 45 extern uint32_t exit_devfs_move; 46 #endif 47 41 48 /////////////////////////////// 42 49 devfs_ctx_t * devfs_ctx_alloc() … … 79 86 error_t error; 80 87 81 devfs_dmsg("\n[D MSG] %s : enter in cluster %x\n",88 devfs_dmsg("\n[DBG] %s : enter in cluster %x\n", 82 89 __FUNCTION__ , local_cxy ); 83 90 … … 93 100 assert( (error == 0) , __FUNCTION__ , "cannot create <dev>\n" ); 94 101 95 devfs_dmsg("\n[D MSG] %s : <dev> created in cluster %x\n",102 devfs_dmsg("\n[DBG] %s : <dev> created in cluster %x\n", 96 103 __FUNCTION__ , local_cxy ); 97 104 … … 107 114 assert( (error == 0) , __FUNCTION__ , "cannot create <external>\n" ); 108 115 109 devfs_dmsg("\n[D MSG] %s : <external> created in cluster %x\n",116 devfs_dmsg("\n[DBG] %s : <external> created in cluster %x\n", 110 117 __FUNCTION__ , local_cxy ); 111 118 } … … 119 126 xptr_t chdev_xp; 120 127 cxy_t chdev_cxy; 128 chdev_t * chdev_ptr; 121 129 xptr_t inode_xp; 122 130 uint32_t channel; … … 132 140 devfs_internal_inode_xp ); 133 141 142 devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n", 143 __FUNCTION__ , node_name , local_cxy ); 144 134 145 // create MMC chdev inode 135 chdev_xp = chdev_dir.mmc[local_cxy];146 chdev_xp = chdev_dir.mmc[local_cxy]; 136 147 if( chdev_xp != XPTR_NULL) 137 148 { 149 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 138 150 vfs_add_child_in_parent( local_cxy, 139 151 INODE_TYPE_DEV, 140 152 FS_TYPE_DEVFS, 141 153 *devfs_internal_inode_xp, 142 "mmc",154 chdev_ptr->name, 143 155 GET_PTR( chdev_xp ), 144 156 &inode_xp ); 157 158 devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n", 159 __FUNCTION__ , chdev_ptr->name , local_cxy ); 160 145 161 } 146 162 … … 151 167 if( chdev_xp != XPTR_NULL) 152 168 { 153 snprintf( node_name , 16 , "dma_%d" , channel);169 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 154 170 vfs_add_child_in_parent( local_cxy, 155 171 INODE_TYPE_DEV, 156 172 FS_TYPE_DEVFS, 157 173 *devfs_internal_inode_xp, 158 node_name,174 chdev_ptr->name, 159 175 GET_PTR( chdev_xp ), 160 176 &inode_xp ); 177 178 devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n", 179 __FUNCTION__ , chdev_ptr->name , local_cxy ); 180 161 181 } 162 182 } … … 167 187 { 168 188 chdev_cxy = GET_CXY( chdev_xp ); 189 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 169 190 if( chdev_cxy == local_cxy ) 170 191 { … … 173 194 FS_TYPE_DEVFS, 174 195 devfs_external_inode_xp, 175 "iob",196 chdev_ptr->name, 176 197 GET_PTR( chdev_xp ), 177 198 &inode_xp ); 199 200 devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n", 201 __FUNCTION__ , chdev_ptr->name , local_cxy ); 202 178 203 } 179 204 } … … 184 209 { 185 210 chdev_cxy = GET_CXY( chdev_xp ); 211 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 186 212 if( chdev_cxy == local_cxy ) 187 213 { … … 190 216 FS_TYPE_DEVFS, 191 217 devfs_external_inode_xp, 192 "pic",218 chdev_ptr->name, 193 219 GET_PTR( chdev_xp ), 194 220 &inode_xp ); 195 } 196 } 197 198 // create a TXT inode in each cluster containing a TXT chdev 221 222 devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n", 223 __FUNCTION__ , chdev_ptr->name , local_cxy ); 224 225 } 226 } 227 228 // create a TXT_RX inode in each cluster containing a TXT_RX chdev 199 229 for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ ) 200 230 { 201 chdev_xp = chdev_dir.txt[channel]; 202 if( chdev_xp != XPTR_NULL ) 203 { 204 chdev_cxy = GET_CXY( chdev_xp ); 205 if( chdev_cxy == local_cxy ) 206 { 207 snprintf( node_name , 16 , "txt_%d" , channel ); 208 vfs_add_child_in_parent( local_cxy, 209 INODE_TYPE_DEV, 210 FS_TYPE_DEVFS, 211 devfs_external_inode_xp, 212 node_name, 213 GET_PTR( chdev_xp ), 214 &inode_xp ); 231 chdev_xp = chdev_dir.txt_rx[channel]; 232 if( chdev_xp != XPTR_NULL ) 233 { 234 chdev_cxy = GET_CXY( chdev_xp ); 235 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 236 if( chdev_cxy == local_cxy ) 237 { 238 vfs_add_child_in_parent( local_cxy, 239 INODE_TYPE_DEV, 240 FS_TYPE_DEVFS, 241 devfs_external_inode_xp, 242 chdev_ptr->name, 243 GET_PTR( chdev_xp ), 244 &inode_xp ); 245 246 devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n", 247 __FUNCTION__ , chdev_ptr->name , local_cxy ); 248 249 } 250 } 251 } 252 253 // create a TXT_TX inode in each cluster containing a TXT_TX chdev 254 for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ ) 255 { 256 chdev_xp = chdev_dir.txt_tx[channel]; 257 if( chdev_xp != XPTR_NULL ) 258 { 259 chdev_cxy = GET_CXY( chdev_xp ); 260 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 261 if( chdev_cxy == local_cxy ) 262 { 263 vfs_add_child_in_parent( local_cxy, 264 INODE_TYPE_DEV, 265 FS_TYPE_DEVFS, 266 devfs_external_inode_xp, 267 chdev_ptr->name, 268 GET_PTR( chdev_xp ), 269 &inode_xp ); 270 271 devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n", 272 __FUNCTION__ , chdev_ptr->name , local_cxy ); 273 215 274 } 216 275 } … … 224 283 { 225 284 chdev_cxy = GET_CXY( chdev_xp ); 226 if( chdev_cxy == local_cxy ) 227 { 228 snprintf( node_name , 16 , "ioc_%d" , channel ); 229 vfs_add_child_in_parent( local_cxy, 230 INODE_TYPE_DEV, 231 FS_TYPE_DEVFS, 232 devfs_external_inode_xp, 233 node_name, 234 GET_PTR( chdev_xp ), 235 &inode_xp ); 285 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 286 if( chdev_cxy == local_cxy ) 287 { 288 vfs_add_child_in_parent( local_cxy, 289 INODE_TYPE_DEV, 290 FS_TYPE_DEVFS, 291 devfs_external_inode_xp, 292 chdev_ptr->name, 293 GET_PTR( chdev_xp ), 294 &inode_xp ); 295 296 devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n", 297 __FUNCTION__ , chdev_ptr->name , local_cxy ); 298 236 299 } 237 300 } … … 245 308 { 246 309 chdev_cxy = GET_CXY( chdev_xp ); 247 if( chdev_cxy == local_cxy ) 248 { 249 snprintf( node_name , 16 , "fbf_%d" , channel ); 250 vfs_add_child_in_parent( local_cxy, 251 INODE_TYPE_DEV, 252 FS_TYPE_DEVFS, 253 devfs_external_inode_xp, 254 node_name, 255 GET_PTR( chdev_xp ), 256 &inode_xp ); 310 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 311 if( chdev_cxy == local_cxy ) 312 { 313 vfs_add_child_in_parent( local_cxy, 314 INODE_TYPE_DEV, 315 FS_TYPE_DEVFS, 316 devfs_external_inode_xp, 317 chdev_ptr->name, 318 GET_PTR( chdev_xp ), 319 &inode_xp ); 320 321 devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n", 322 __FUNCTION__ , chdev_ptr->name , local_cxy ); 323 257 324 } 258 325 } … … 266 333 { 267 334 chdev_cxy = GET_CXY( chdev_xp ); 268 if( chdev_cxy == local_cxy ) 269 { 270 snprintf( node_name , 16 , "nic_rx_%d" , channel ); 271 vfs_add_child_in_parent( local_cxy, 272 INODE_TYPE_DEV, 273 FS_TYPE_DEVFS, 274 devfs_external_inode_xp, 275 node_name, 276 GET_PTR( chdev_xp ), 277 &inode_xp ); 335 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 336 if( chdev_cxy == local_cxy ) 337 { 338 vfs_add_child_in_parent( local_cxy, 339 INODE_TYPE_DEV, 340 FS_TYPE_DEVFS, 341 devfs_external_inode_xp, 342 chdev_ptr->name, 343 GET_PTR( chdev_xp ), 344 &inode_xp ); 345 346 devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n", 347 __FUNCTION__ , chdev_ptr->name , local_cxy ); 348 278 349 } 279 350 } … … 287 358 { 288 359 chdev_cxy = GET_CXY( chdev_xp ); 289 if( chdev_cxy == local_cxy ) 290 { 291 snprintf( node_name , 16 , "nic_tx_%d" , channel ); 292 vfs_add_child_in_parent( local_cxy, 293 INODE_TYPE_DEV, 294 FS_TYPE_DEVFS, 295 devfs_external_inode_xp, 296 node_name, 297 GET_PTR( chdev_xp ), 298 &inode_xp ); 360 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 361 if( chdev_cxy == local_cxy ) 362 { 363 vfs_add_child_in_parent( local_cxy, 364 INODE_TYPE_DEV, 365 FS_TYPE_DEVFS, 366 devfs_external_inode_xp, 367 chdev_ptr->name, 368 GET_PTR( chdev_xp ), 369 &inode_xp ); 370 371 devfs_dmsg("\n[DBG] %s : created <%s> inode in cluster %x\n", 372 __FUNCTION__ , chdev_ptr->name , local_cxy ); 373 299 374 } 300 375 } … … 302 377 } // end devfs_local_init() 303 378 379 ////////////////////////////////////////// 380 int devfs_user_move( bool_t to_buffer, 381 xptr_t file_xp, 382 void * u_buf, 383 uint32_t size ) 384 { 385 assert( ( file_xp != XPTR_NULL ) , __FUNCTION__ , "file_xp == XPTR_NULL" ); 386 387 assert( ( size < CONFIG_TXT_KBUF_SIZE ) , __FUNCTION__ , "string size too large" ); 388 389 cxy_t file_cxy; // remote file descriptor cluster 390 vfs_file_t * file_ptr; // remote file descriptor local pointer 391 vfs_inode_type_t inode_type; // associated inode type 392 vfs_inode_t * inode_ptr; // associated inode local pointer 393 chdev_t * chdev_ptr; // associated chdev type 394 uint32_t func; // chdev functionnal type 395 uint32_t channel; // chdev channel index 396 error_t error; 397 398 char k_buf[CONFIG_TXT_KBUF_SIZE]; // local kernel buffer 399 400 devfs_dmsg("\n[DBG] %s enter / cycle %d\n", 401 __FUNCTION__ , hal_time_stamp() ); 402 403 #if CONFIG_READ_DEBUG 404 enter_devfs_move = hal_time_stamp(); 405 #endif 406 407 // get cluster and local pointer on remote file descriptor 408 // associated inode and chdev are stored in same cluster as the file desc. 409 file_cxy = GET_CXY( file_xp ); 410 file_ptr = (vfs_file_t *)GET_PTR( file_xp ); 411 412 // get inode type from remote file descriptor 413 inode_type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type ) ); 414 inode_ptr = (vfs_inode_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) ); 415 416 assert( (inode_type == INODE_TYPE_DEV) , __FUNCTION__ , 417 "inode type is not INODE_TYPE_DEV" ); 418 419 // get chdev local pointer from remote inode extension 420 chdev_ptr = (chdev_t *)hal_remote_lpt( XPTR( file_cxy , &inode_ptr->extend ) ); 421 422 // get chdev functionnal type and channel 423 func = hal_remote_lw( XPTR( file_cxy , &chdev_ptr->func ) ); 424 channel = hal_remote_lw( XPTR( file_cxy , &chdev_ptr->channel ) ); 425 426 // action depends on "func" and "to_buffer" 427 if( func == DEV_FUNC_TXT ) 428 { 429 if( to_buffer ) // TXT read 430 { 431 uint32_t i; 432 for( i = 0 ; i < size ; i++ ) 433 { 434 error = dev_txt_read( channel , &k_buf[i] ); 435 436 if( error ) 437 { 438 439 devfs_dmsg("\n[DBG] %s exit error / cycle %d\n", 440 __FUNCTION__ , hal_time_stamp() ); 441 442 return -1; 443 } 444 else 445 { 446 hal_strcpy_to_uspace( u_buf , k_buf , size ); 447 } 448 } 449 450 #if CONFIG_READ_DEBUG 451 exit_devfs_move = hal_time_stamp(); 452 #endif 453 454 devfs_dmsg("\n[DBG] %s exit success / size = %d / cycle %d\n", 455 __FUNCTION__ , size , hal_time_stamp() ); 456 457 return size; 458 } 459 else // TXT write 460 { 461 hal_strcpy_from_uspace( k_buf , u_buf , size ); 462 463 error = dev_txt_write( channel , k_buf , size ); 464 if( error ) 465 { 466 467 devfs_dmsg("\n[DBG] %s exit error / cycle %d\n", 468 __FUNCTION__ , hal_time_stamp() ); 469 470 return -1; 471 } 472 else 473 { 474 475 devfs_dmsg("\n[DBG] %s exit success / size = %d / cycle %d\n", 476 __FUNCTION__ , size , hal_time_stamp() ); 477 478 return size; 479 } 480 } 481 } 482 else 483 { 484 panic("device type %s does not support direct user access", chdev_func_str(func) ); 485 486 return -1; 487 } 488 } // end devfs_user_move() 489 490 -
trunk/kernel/fs/devfs.h
r238 r407 41 41 // 42 42 // The DEVFS extensions to the generic VFS are the following: 43 // 1) The vfs_ctx_t "extend" field is a void*pointing on the devfs_ctx_t structure.43 // 1) The vfs_ctx_t "extend" void* field is pointing on the devfs_ctx_t structure. 44 44 // This structure contains two extended pointers on the DEVFS "dev" directory inode, 45 45 // and on the "external" directory inode. 46 // 2) The vfs_inode_t "extend" field is a void*, pointing on the associated 47 // chdev descriptor. 46 // 2) The vfs_inode_t "extend" void* field is pointing on the chdev descriptor. 48 47 ////////////////////////////////////////////////////////////////////////////////////////// 49 48 … … 119 118 xptr_t * devfs_internal_inode_xp ); 120 119 120 /****************************************************************************************** 121 * This function moves <size> bytes between a device, and a - possibly distributed - 122 * user space <buffer>. It uses the <file_xp> and <to_buffer> arguments, to call the 123 * relevant device access function. 124 * It is called by the sys_read() and sys_write() functions. 125 * The <size> argument cannot be larger than the CONFIG_TXT_KBUF_SIZE configuration 126 * parameter, as this function makes a copy between the user space buffer, and a local 127 * kernel buffer allocated in the kernel stack. 128 ****************************************************************************************** 129 * @ to_buffer : device -> buffer if true / buffer -> device if false. 130 * @ file_xp : extended pointer on the remote file descriptor. 131 * @ u_buf : user space buffer (virtual address). 132 * @ size : requested number of bytes from offset. 133 * @ returns number of bytes actually moved if success / -1 if error. 134 *****************************************************************************************/ 135 int devfs_user_move( bool_t to_buffer, 136 xptr_t file_xp, 137 void * u_buf, 138 uint32_t size ); 139 140 121 141 #endif /* _DEVFS_H_ */ -
trunk/kernel/fs/fatfs.c
r406 r407 262 262 "no FAT access required for first page\n"); 263 263 264 fatfs_dmsg("\n[DMSG] %s : enter / first_cluster_id = %d / searched_page_index = %d\n",265 __FUNCTION__ , first_cluster_id, searched_page_index );264 fatfs_dmsg("\n[DBG] %s : core[%x,%d] enters / first_cluster_id = %d / searched_index = %d\n", 265 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, first_cluster_id, searched_page_index ); 266 266 267 267 // get number of FAT slots per page … … 289 289 next_cluster_id = current_page_buffer[current_page_offset]; 290 290 291 fatfs_dmsg("\n[DMSG] %s : traverse FAT / current_page_index = %d\n" 292 " current_page_offset = %d / next_cluster_id = %d\n", 293 __FUNCTION__ , current_page_index , current_page_offset , next_cluster_id ); 291 fatfs_dmsg("\n[DBG] %s : core[%x,%d] traverse FAT / current_page_index = %d\n" 292 "current_page_offset = %d / next_cluster_id = %d\n", 293 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, current_page_index, 294 current_page_offset , next_cluster_id ); 294 295 295 296 // update loop variables … … 301 302 if( next_cluster_id == 0xFFFFFFFF ) return EIO; 302 303 303 fatfs_dmsg("\n[DMSG] %s : exit / cluster_id = %d\n", __FUNCTION__ , next_cluster_id ); 304 fatfs_dmsg("\n[DBG] %s : core[%x;%d] exit / cluster_id = %d\n", 305 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, next_cluster_id ); 304 306 305 307 *searched_cluster_id = next_cluster_id; … … 333 335 uint8_t * buffer; 334 336 335 fatfs_dmsg("\n[D MSG] %s : enter for fatfs_ctx = %x\n",337 fatfs_dmsg("\n[DBG] %s : enter for fatfs_ctx = %x\n", 336 338 __FUNCTION__ , fatfs_ctx ); 337 339 … … 347 349 "cannot allocate memory for 512 bytes buffer\n" ); 348 350 349 fatfs_dmsg("\n[D MSG] %s : allocated 512 bytes buffer\n", __FUNCTION__ );351 fatfs_dmsg("\n[DBG] %s : allocated 512 bytes buffer\n", __FUNCTION__ ); 350 352 351 353 // load the boot record from device … … 353 355 error = dev_ioc_sync_read( buffer , 0 , 1 ); 354 356 355 fatfs_dmsg("\n[DMSG] %s : buffer loaded\n", __FUNCTION__ );357 fatfs_dmsg("\n[DBG] %s : buffer loaded\n", __FUNCTION__ ); 356 358 357 359 assert( (error == 0) , __FUNCTION__ , "cannot access boot record\n" ); … … 415 417 kmem_free( &req ); 416 418 417 fatfs_dmsg("\n[D MSG] %s : boot record read & released\n",419 fatfs_dmsg("\n[DBG] %s : boot record read & released\n", 418 420 __FUNCTION__ ); 419 421 … … 437 439 fatfs_ctx->fat_mapper_xp = XPTR( local_cxy , fat_mapper ); 438 440 439 fatfs_dmsg("\n[DMSG] %s : exit for fatfs_ctx = %x\n", 440 __FUNCTION__ , fatfs_ctx ); 441 fatfs_dmsg("\n[DBG] %s : exit for fatfs_ctx = %x\n", __FUNCTION__ , fatfs_ctx ); 441 442 442 443 } // end fatfs_ctx_init() … … 471 472 inode = mapper->inode; 472 473 473 fatfs_dmsg("\n[DMSG] %s : core[%x,%d] enter for page %d / inode %x / mapper %x\n",474 474 fatfs_dmsg("\n[DBG] %s : core[%x,%d] enter for page %d / inode %x / mapper %x\n", 475 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , index , inode , mapper ); 475 476 476 477 // get page base address … … 488 489 lba = fatfs_ctx->fat_begin_lba + (count * index); 489 490 490 fatfs_dmsg("\n[DMSG] %s : core[%x,%d] access FAT on device / lba = %d\n",491 491 fatfs_dmsg("\n[DBG] %s : core[%x,%d] access FAT on device / lba = %d\n", 492 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , lba ); 492 493 493 494 // access device … … 511 512 else // FAT mapper access required 512 513 { 513 fatfs_dmsg("\n[DMSG] %s : core[%x,%d] must access FAT\n",514 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );515 516 514 // get cluster and local pointer on FAT mapper 517 515 xptr_t fat_mapper_xp = fatfs_ctx->fat_mapper_xp; … … 522 520 if( fat_mapper_cxy == local_cxy ) // FAT mapper is local 523 521 { 522 523 fatfs_dmsg("\n[DBG] %s : core[%x,%d] access local FAT mapper\n" 524 "fat_mapper_cxy = %x / fat_mapper_ptr = %x / first_cluster_id = %d / index = %d\n", 525 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , 526 fat_mapper_cxy , fat_mapper_ptr , first_cluster_id , index ); 527 524 528 error = fatfs_get_cluster( fat_mapper_ptr, 525 529 first_cluster_id, … … 529 533 else // FAT mapper is remote 530 534 { 535 536 fatfs_dmsg("\n[DBG] %s : core[%x,%d] access remote FAT mapper\n" 537 "fat_mapper_cxy = %x / fat_mapper_ptr = %x / first_cluster_id = %d / index = %d\n", 538 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , 539 fat_mapper_cxy , fat_mapper_ptr , first_cluster_id , index ); 540 531 541 rpc_fatfs_get_cluster_client( fat_mapper_cxy, 532 542 fat_mapper_ptr, … … 540 550 } 541 551 542 fatfs_dmsg("\n[DMSG] %s : core[%x,%d] access device for inode %x / cluster_id %d\n",543 552 fatfs_dmsg("\n[DBG] %s : core[%x,%d] access device for inode %x / cluster_id %d\n", 553 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , inode , searched_cluster_id ); 544 554 545 555 // get lba from cluster_id … … 553 563 } 554 564 555 fatfs_dmsg("\n[DMSG] %s : core[%x,%d] exit for page %d / inode %x / mapper %x\n",556 565 fatfs_dmsg("\n[DBG] %s : core[%x,%d] exit for page %d / inode %x / mapper %x\n", 566 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , index , inode , mapper ); 557 567 558 568 #if (CONFIG_FATFS_DEBUG & 0x1) … … 584 594 // - scan the directory entries in each 4 Kbytes page 585 595 586 fatfs_dmsg("\n[DMSG] %s : enter for child <%s> in parent inode %l\n",587 596 fatfs_dmsg("\n[DBG] %s : enter for child <%s> in parent inode %l\n", 597 __FUNCTION__ , name , XPTR( local_cxy , parent_inode ) ); 588 598 589 599 mapper_t * mapper = parent_inode->mapper; … … 705 715 if ( found == -1 ) // found end of directory => failure 706 716 { 707 fatfs_dmsg("\n[DMSG] %s : exit / child <%s> not found in parent inode %l\n", 708 __FUNCTION__ , name , XPTR( local_cxy , parent_inode ) ); 717 718 fatfs_dmsg("\n[DBG] %s : exit / child <%s> not found in parent inode %l\n", 719 __FUNCTION__ , name , XPTR( local_cxy , parent_inode ) ); 709 720 710 721 return ENOENT; … … 723 734 hal_remote_sw( XPTR( child_cxy , &child_ptr->extend ) , cluster ); 724 735 725 fatfs_dmsg("\n[DMSG] %s : exit / child <%s> found in parent inode %l\n",726 736 fatfs_dmsg("\n[DBG] %s : exit / child <%s> found in parent inode %l\n", 737 __FUNCTION__ , name , XPTR( local_cxy , parent_inode ) ); 727 738 728 739 return 0; -
trunk/kernel/fs/vfs.c
r406 r407 156 156 error_t error; 157 157 158 vfs_dmsg("\n[INFO] %s : core[%x,%d] enter / dentry_xp = %l\n",159 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , dentry_xp);158 vfs_dmsg("\n[DBG] %s : core[%x,%d] enter / dentry = %x in cluster %x\n", 159 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, GET_PTR(dentry_xp), GET_CXY(dentry_xp) ); 160 160 161 161 // check fs type and get pointer on context … … 229 229 remote_spinlock_init( XPTR( local_cxy , &inode->main_lock ) ); 230 230 231 vfs_dmsg("\n[INFO] %s : core[%x,%d] exit / inode_xp = %l / dentry_xp = %l\n",232 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, XPTR(local_cxy,inode), dentry_xp);231 vfs_dmsg("\n[DBG] %s : core[%x,%d] exit / inode = %x in cluster %x\n", 232 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, inode , local_cxy ); 233 233 234 234 // return extended pointer on inode … … 262 262 xptr_t child_xp ) 263 263 { 264 vfs_dmsg("\n[INFO] %s : core[%x,%d] enter for <%s> / cycle %d\n",265 264 vfs_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s> / cycle %d\n", 265 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , name , hal_time_stamp() ); 266 266 267 267 error_t error = 0; … … 292 292 } 293 293 294 vfs_dmsg("\n[INFO] %s : core[%x,%d] exit for <%s> / cycle %d\n",295 294 vfs_dmsg("\n[DBG] %s : core[%x,%d] exit for <%s> / cycle %d\n", 295 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , name , hal_time_stamp() ); 296 296 297 297 return error; … … 413 413 414 414 // display inode header 415 printk("\n*** inode <%s> / inode_xp = %l / dentry_xp = %l ***\n",416 name , inode_xp , dentry_xp);415 printk("\n***** inode <%s> [%x in cluster %x]\n", 416 name , GET_PTR(inode_xp) , GET_CXY(inode_xp) ); 417 417 418 418 // display children from xhtab … … 435 435 kmem_req_t req; // request to kernel memory allocator 436 436 437 vfs_dmsg("\n[INFO] %s : core[%x,%d] enter for <%s> / parent inode = %x / cycle %d\n",438 437 vfs_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s> / parent inode = %x / cycle %d\n", 438 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, name, parent, hal_time_stamp() ); 439 439 440 440 // get pointer on context … … 484 484 *dentry_xp = XPTR( local_cxy , dentry ); 485 485 486 vfs_dmsg("\n[INFO] %s : core[%x,%d] exit for <%s> / dentry = %l/ cycle %d\n",487 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, name, *dentry_xp, hal_time_stamp() );486 vfs_dmsg("\n[DBG] %s : core[%x,%d] exit for <%s> / dentry = %x in cluster %x / cycle %d\n", 487 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, name, dentry, local_cxy , hal_time_stamp() ); 488 488 489 489 return 0; … … 586 586 ////////////////////////////////////////////////////////////////////////////////////////// 587 587 588 //////////////////////////////////// 589 error_t vfs_open( xptr_t cwd_xp,590 char * path,591 uint32_t flags,592 uint32_t mode,593 xptr_t * new_file_xp,594 uint32_t * new_file_id )588 ////////////////////////////////////// 589 error_t vfs_open( process_t * process, 590 char * path, 591 uint32_t flags, 592 uint32_t mode, 593 xptr_t * new_file_xp, 594 uint32_t * new_file_id ) 595 595 { 596 596 error_t error; … … 603 603 uint32_t file_id; // created file descriptor index in reference fd_array 604 604 605 vfs_dmsg("\n[INFO] %s : core[%x,%d] enter for <%s> / cycle %d\n",606 605 vfs_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s> / cycle %d\n", 606 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path, (uint32_t)hal_time_stamp() ); 607 607 608 608 // compute lookup working mode … … 614 614 // compute attributes for the created file 615 615 file_attr = 0; 616 if( (flags & O_RDONLY ) == 0 ) file_attr |= FD_ATTR_ READ_ENABLE;617 if( (flags & O_WRONLY ) == 0 ) file_attr |= FD_ATTR_ WRITE_ENABLE;616 if( (flags & O_RDONLY ) == 0 ) file_attr |= FD_ATTR_WRITE_ENABLE; 617 if( (flags & O_WRONLY ) == 0 ) file_attr |= FD_ATTR_READ_ENABLE; 618 618 if( (flags & O_SYNC ) ) file_attr |= FD_ATTR_SYNC; 619 619 if( (flags & O_APPEND ) ) file_attr |= FD_ATTR_APPEND; … … 621 621 622 622 // get extended pointer on target inode 623 error = vfs_lookup( cwd_xp , path , lookup_mode , &inode_xp );623 error = vfs_lookup( process->vfs_cwd_xp , path , lookup_mode , &inode_xp ); 624 624 625 625 if( error ) return error; … … 629 629 inode_ptr = (vfs_inode_t *)GET_PTR( inode_xp ); 630 630 631 vfs_dmsg("\n[DBG] %s : core[%x,%d] found inode for <%s> in cluster %x / cycle %d\n", 632 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path, inode_cxy , (uint32_t)hal_time_stamp() ); 633 631 634 // create a new file descriptor in cluster containing inode 632 635 if( inode_cxy == local_cxy ) // target cluster is local … … 641 644 if( error ) return error; 642 645 643 // allocate and register a new file descriptor index in reference cluster fd_array644 error = process_fd_register( file_xp , &file_id );646 // allocate and register a new file descriptor index in reference process 647 error = process_fd_register( process , file_xp , &file_id ); 645 648 646 649 if( error ) return error; 647 650 648 vfs_dmsg("\n[INFO] %s : core[%x,%d] exit for <%s> / file_xp = %l / cycle %d\n", 649 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path, file_xp, hal_time_stamp() ); 651 vfs_dmsg("\n[DBG] %s : core[%x,%d] exit for <%s> / file = %x in cluster %x / cycle %d\n", 652 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path, 653 GET_PTR(file_xp), GET_CXY(file_xp), hal_time_stamp() ); 650 654 651 655 // success … … 656 660 } // end vfs_open() 657 661 658 //////////////////////////////////////////// 659 error_t vfs_user_move( bool_t to_buffer, 660 xptr_t file_xp, 661 void * buffer, 662 uint32_t size ) 663 { 664 assert( ( file_xp != XPTR_NULL ) , __FUNCTION__ , "file_xp == XPTR_NULL" ); 662 ////////////////////////////////////// 663 int vfs_user_move( bool_t to_buffer, 664 xptr_t file_xp, 665 void * buffer, 666 uint32_t size ) 667 { 668 assert( ( file_xp != XPTR_NULL ) , __FUNCTION__ , 669 "file_xp == XPTR_NULL" ); 665 670 666 671 cxy_t file_cxy; // remote file descriptor cluster … … 678 683 inode_type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type ) ); 679 684 680 // action depends on inode type 681 if( inode_type == INODE_TYPE_FILE ) 682 { 683 // get mapper pointer and file offset from file descriptor 684 file_offset = hal_remote_lw( XPTR( file_cxy , &file_ptr->offset ) ); 685 mapper = (mapper_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) ); 686 687 // move data between mapper and buffer 688 if( file_cxy == local_cxy ) 689 { 690 error = mapper_move_user( mapper, 691 to_buffer, 692 file_offset, 693 buffer, 694 size ); 695 } 696 else 697 { 698 rpc_mapper_move_buffer_client( file_cxy, 699 mapper, 700 to_buffer, 701 true, // user buffer 702 file_offset, 703 (uint64_t)(intptr_t)buffer, 704 size, 705 &error ); 706 } 707 708 if( error ) return -1; 709 else return 0; 710 } 711 else 712 { 713 printk("\n[ERROR] in %s : inode is not a file", __FUNCTION__ ); 714 return -1; 715 } 685 assert( (inode_type == INODE_TYPE_FILE) , __FUNCTION__ , 686 "inode type is not INODE_TYPE_FILE" ); 687 688 // get mapper pointer and file offset from file descriptor 689 file_offset = hal_remote_lw( XPTR( file_cxy , &file_ptr->offset ) ); 690 mapper = (mapper_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) ); 691 692 // move data between mapper and buffer 693 if( file_cxy == local_cxy ) 694 { 695 error = mapper_move_user( mapper, 696 to_buffer, 697 file_offset, 698 buffer, 699 size ); 700 } 701 else 702 { 703 rpc_mapper_move_buffer_client( file_cxy, 704 mapper, 705 to_buffer, 706 true, // user buffer 707 file_offset, 708 (uint64_t)(intptr_t)buffer, 709 size, 710 &error ); 711 } 712 713 if( error ) return -1; 714 else return size; 715 716 716 } // end vfs_user_move() 717 717 … … 905 905 panic("not implemented"); 906 906 return 0; 907 } // vfs_unlink()908 909 /////////////////////////////////////// 910 error_t vfs_stat( xptr_t file_xp,911 vfs_stat_t * k_stat )907 } 908 909 //////////////////////////////////////// 910 error_t vfs_stat( xptr_t file_xp, 911 struct stat * k_stat ) 912 912 { 913 913 panic("not implemented"); … … 915 915 } 916 916 917 //////////////////////////////////////////// 918 error_t vfs_readdir( xptr_t file_xp,919 vfs_dirent_t * k_dirent )917 ///////////////////////////////////////////// 918 error_t vfs_readdir( xptr_t file_xp, 919 struct dirent * k_dirent ) 920 920 { 921 921 panic("not implemented"); … … 1094 1094 1095 1095 // display inode 1096 nolock_printk("%s%s <%s> : inode = % l / mapper = %l / dentry = %l\n",1096 nolock_printk("%s%s <%s> : inode = %x / mapper = %x / cluster %x\n", 1097 1097 indent_str[indent], vfs_inode_type_str( inode_type ), name, 1098 inode_ xp , XPTR( inode_cxy , mapper_ptr ) , dentry_xp);1098 inode_ptr , mapper_ptr , inode_cxy ); 1099 1099 1100 1100 // scan directory entries … … 1171 1171 1172 1172 // get pointers on TXT0 chdev 1173 xptr_t txt0_xp = chdev_dir.txt [0];1173 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 1174 1174 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 1175 1175 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); … … 1338 1338 process = this->process; 1339 1339 1340 vfs_dmsg("\n[INFO] %s : core[%x,%d] enter for <%s> / cycle %d\n",1341 1340 vfs_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s> / cycle %d\n", 1341 __FUNCTION__ , local_cxy , this->core->lid , pathname , hal_time_stamp() ); 1342 1342 1343 1343 // get extended pointer on first inode to search … … 1362 1362 vfs_get_name_from_path( current , name , &next , &last ); 1363 1363 1364 vfs_dmsg("\n[INFO] %s : core[%x,%d] look for <%s> / last = %d\n",1365 1364 vfs_dmsg("\n[DBG] %s : core[%x,%d] look for <%s> / last = %d\n", 1365 __FUNCTION__ , local_cxy , this->core->lid , name , last ); 1366 1366 1367 1367 // search a child dentry matching name in parent inode … … 1380 1380 if (found == false ) // child node not found in inode tree 1381 1381 { 1382 vfs_dmsg("\n[INFO] %s : core[%x,%d] miss <%s> => load it\n", 1383 __FUNCTION__ , local_cxy , this->core->lid , name ); 1382 1383 vfs_dmsg("\n[DBG] %s : core[%x,%d] miss <%s> => load it\n", 1384 __FUNCTION__ , local_cxy , this->core->lid , name ); 1384 1385 1385 1386 // release lock on parent inode … … 1405 1406 if( error ) 1406 1407 { 1407 printk("\n[ERROR] in %s : no memory for inode %s in path %s\n",1408 printk("\n[ERROR] in %s : no memory for inode <%s> in path <%s>\n", 1408 1409 __FUNCTION__ , name , pathname ); 1409 1410 return ENOMEM; … … 1428 1429 if ( error ) 1429 1430 { 1430 printk("\n[ERROR] in %s : core[%x,%d] / <%s> no t found in parent\n",1431 __FUNCTION__ , local_cxy , this->core->lid , name );1431 printk("\n[ERROR] in %s : core[%x,%d] / <%s> node not found in <%s>\n", 1432 __FUNCTION__ , local_cxy , this->core->lid , name , pathname ); 1432 1433 return ENOENT; 1433 1434 } … … 1464 1465 vfs_inode_lock( parent_xp ); 1465 1466 1466 vfs_dmsg("\n[INFO] %s : core[%x,%d] created node <%s>\n", 1467 __FUNCTION__ , local_cxy , this->core->lid , name ); 1467 vfs_dmsg("\n[DBG] %s : core[%x,%d] created node <%s>\n", 1468 __FUNCTION__ , local_cxy , this->core->lid , name ); 1469 1468 1470 } 1469 1471 1470 vfs_dmsg("\n[INFO] %s : core[%x,%d] found <%s> / parent = %l / child = %l\n",1471 __FUNCTION__ , local_cxy , this->core->lid , name , parent_xp , child_xp);1472 vfs_dmsg("\n[DBG] %s : core[%x,%d] found <%s> / inode = %x in cluster %x\n", 1473 __FUNCTION__ , local_cxy , this->core->lid , name , GET_PTR(child_xp) , GET_CXY(child_xp) ); 1472 1474 1473 1475 // TODO check access rights here [AG] … … 1494 1496 vfs_inode_unlock( parent_xp ); 1495 1497 1496 vfs_dmsg("\n[INFO] %s : exit <%s> found / inode = %l\n",1497 __FUNCTION__ , pathname , child_xp);1498 vfs_dmsg("\n[DBG] %s : core[%x,%d] exit for <%s> / inode = %x in cluster %x\n", 1499 __FUNCTION__,local_cxy,this->core->lid,pathname,GET_PTR(child_xp),GET_CXY(child_xp) ); 1498 1500 1499 1501 // return searched pointer … … 1593 1595 parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp ); 1594 1596 1595 vfs_dmsg("\n[INFO] %s : enter for <%s> / core[%x,%d] / child_cxy = %x / parent_xp = %l\n",1596 __FUNCTION__ , name , local_cxy , CURRENT_THREAD->core->lid , child_cxy , parent_xp);1597 vfs_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s> / child_cxy = %x / parent_cxy = %x\n", 1598 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , name , child_cxy , parent_cxy ); 1597 1599 1598 1600 // 1. create dentry … … 1604 1606 &dentry_xp ); 1605 1607 1606 vfs_dmsg("\n[INFO] %s : dentry <%s> created in local cluster %x\n", 1607 __FUNCTION__ , name , local_cxy ); 1608 vfs_dmsg("\n[DBG] %s : dentry <%s> created in local cluster %x\n", 1609 __FUNCTION__ , name , local_cxy ); 1610 1608 1611 } 1609 1612 else // parent cluster is remote … … 1616 1619 &error ); 1617 1620 1618 vfs_dmsg("\n[INFO] %s : dentry <%s> created in remote cluster %x\n", 1619 __FUNCTION__ , name , parent_cxy ); 1621 vfs_dmsg("\n[DBG] %s : dentry <%s> created in remote cluster %x\n", 1622 __FUNCTION__ , name , parent_cxy ); 1623 1620 1624 } 1621 1625 … … 1623 1627 { 1624 1628 printk("\n[ERROR] in %s : cannot create dentry in cluster %x\n", 1625 1629 __FUNCTION__ , parent_cxy ); 1626 1630 return ENOMEM; 1627 1631 } … … 1645 1649 &inode_xp ); 1646 1650 1647 vfs_dmsg("\n[INFO] %s : inode %l created in local cluster %x\n", 1648 __FUNCTION__ , inode_xp , local_cxy ); 1651 vfs_dmsg("\n[DBG] %s : inode %x created in local cluster %x\n", 1652 __FUNCTION__ , GET_PTR(inode_xp) , local_cxy ); 1653 1649 1654 } 1650 1655 else // child cluster is remote … … 1662 1667 &error ); 1663 1668 1664 vfs_dmsg("\n[INFO] %s : inode %l created in remote cluster %x\n", 1665 __FUNCTION__ , inode_xp , child_cxy ); 1669 vfs_dmsg("\n[DBG] %s : inode %x created in remote cluster %x\n", 1670 __FUNCTION__ , GET_PTR(inode_xp) , child_cxy ); 1671 1666 1672 } 1667 1673 … … 1682 1688 hal_remote_swd( XPTR( dentry_cxy , &dentry_ptr->child_xp ) , inode_xp ); 1683 1689 1684 vfs_dmsg("\n[INFO] %s : exit in cluster %x for <%s>\n",1685 1690 vfs_dmsg("\n[DBG] %s : exit in cluster %x for <%s>\n", 1691 __FUNCTION__ , local_cxy , name ); 1686 1692 1687 1693 // success : return extended pointer on child inode … … 1707 1713 assert( (mapper != NULL) , __FUNCTION__ , "no mapper for page\n" ); 1708 1714 1709 vfs_dmsg("\n[DMSG] %s : enters for page %d / inode_cxy = %x / inode_ptr= %x\n",1710 __FUNCTION__ , page->index , local_cxy, mapper->inode );1715 vfs_dmsg("\n[DBG] %s : core[%x,%d] enters for page %d / mapper = %x / inode = %x\n", 1716 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid , page->index , mapper, mapper->inode ); 1711 1717 1712 1718 // get FS type … … 1733 1739 } 1734 1740 1735 vfs_dmsg("\n[DMSG] %s : exit for page %d / inode_cxy = %x / inode_ptr= %x\n",1736 __FUNCTION__ , page->index , local_cxy, mapper->inode );1741 vfs_dmsg("\n[DBG] %s : core[%x,%d] exit for page %d / mapper = %x / inode = %x\n", 1742 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, page->index, mapper, mapper->inode ); 1737 1743 1738 1744 return error; … … 1753 1759 assert( (mapper != NULL) , __FUNCTION__ , "mapper pointer is NULL\n" ); 1754 1760 1755 vfs_dmsg("\n[INFO] %s : core[%x,%d] enter for inode %l/ cycle %d\n",1756 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, XPTR(local_cxy , inode) );1761 vfs_dmsg("\n[DBG] %s : core[%x,%d] enter for inode %x in cluster %x/ cycle %d\n", 1762 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, inode , local_cxy , hal_time_stamp() ); 1757 1763 1758 1764 // compute number of pages … … 1770 1776 } 1771 1777 1772 vfs_dmsg("\n[INFO] %s : core[%x,%d] exit for inode %l/ cycle %d\n",1773 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, XPTR(local_cxy , inode) );1778 vfs_dmsg("\n[DBG] %s : core[%x,%d] exit for inode %x in cluster %x / cycle %d\n", 1779 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, inode , local_cxy , hal_time_stamp() ); 1774 1780 1775 1781 return 0; -
trunk/kernel/fs/vfs.h
r317 r407 38 38 #include <xhtab.h> 39 39 #include <errno.h> 40 #include <metafs.h> 41 40 #include <shared_syscalls.h> 42 41 #include <fatfs.h> 43 42 #include <ramfs.h> … … 235 234 typedef enum 236 235 { 237 VFS_SEEK_SET,238 VFS_SEEK_CUR,239 VFS_SEEK_END,240 }241 vfs_lseek_cmd_t;242 243 typedef enum244 {245 236 FD_ATTR_READ_ENABLE = 0x01, /*! read access possible */ 246 237 FD_ATTR_WRITE_ENABLE = 0x02, /*! write access possible */ … … 267 258 vfs_file_t; 268 259 269 /******************************************************************************************270 * This structure define the informations associated to a file descriptor,271 * returned to user space by the stat() system call.272 *****************************************************************************************/273 274 typedef struct vfs_stat_s275 {276 uint32_t dev; /*! ID of device containing file */277 uint32_t ino; /*! inode number */278 uint32_t mode; /*! protection */279 uint32_t nlink; /*! number of hard links */280 uint32_t uid; /*! user ID of owner */281 uint32_t gid; /*! group ID of owner */282 uint32_t rdev; /*! device ID (if special file) */283 uint64_t size; /*! total size, in bytes */284 uint32_t blksize; /*! blocksize for file system I/O */285 uint32_t blocks; /*! number of 512B blocks allocated */286 uint64_t atime; /*! time of last access */287 uint64_t mtime; /*! time of last modification */288 uint64_t ctime; /*! time of last status change */289 }290 vfs_stat_t;291 292 /*********************************************************************************************293 * This structure defines the information associated to a directory entry,294 * returned to user space by the readdir() system call.295 ********************************************************************************************/296 297 typedef struct vfs_dirent_s298 {299 uint32_t inum; /*! inode identifier */300 uint32_t type; /*! inode type */301 char name[CONFIG_VFS_MAX_NAME_LENGTH]; /*! dentry name */302 }303 vfs_dirent_t;304 305 306 260 307 261 /*****************************************************************************************/ … … 503 457 error_t vfs_inode_unlink( vfs_inode_t * inode ); 504 458 505 /******************************************************************************************506 * This function TODO507 *****************************************************************************************/508 error_t vfs_inode_stat( vfs_inode_t * inode,509 uint32_t inum );510 511 /******************************************************************************************512 * This function TODO513 *****************************************************************************************/514 error_t vfs_icache_del( vfs_inode_t * inode );515 516 517 /******************************************************************************************518 * This function TODO Pourquoi 2 arguments ?519 *****************************************************************************************/520 error_t vfs_stat_inode( vfs_inode_t * inode,521 uint32_t inum );522 523 459 524 460 /*****************************************************************************************/ … … 643 579 * @ lookup_mode : flags defining the working mode (defined above in this file). 644 580 * @ inode_xp : [out] buffer for extended pointer on searched inode. 645 * @ return 0 if success / ENOENT if inode not found , EACCES if permisso pn denied,646 * EAGAIN if a new complete lookup must be made581 * @ return 0 if success / ENOENT if inode not found , EACCES if permisson denied, 582 * EAGAIN if a new complete lookup must be made 647 583 *****************************************************************************************/ 648 584 error_t vfs_lookup( xptr_t cwd_xp, … … 653 589 /****************************************************************************************** 654 590 * This function creates a new couple dentry/inode, and insert it in the Inode-Tree. 655 * It can be executed by any thread running in any cluster ( can be differentefrom both591 * It can be executed by any thread running in any cluster (can be different from both 656 592 * the child cluster and the parent cluster), as it uses the rpc_dentry_create_client() 657 593 * and rpc_inode_create client() if required. This is done in three steps: … … 707 643 /****************************************************************************************** 708 644 * This function allocates a vfs_file_t structure in the cluster containing the inode 709 * associated to the file identified by <cwd_xp> & <path>. 710 * It initializes it, register it in the reference process fd_array, and returns both 711 * the extended pointer on the remote file descriptor, and the index in the fd_array. 645 * associated to the file identified by the <cwd_xp> & <path> arguments. 646 * It initializes it, register it in the reference process fd_array identified by the 647 * <process> argument, and returns both the extended pointer on the file descriptor, 648 * and the allocated index in the fd_array. 712 649 * The pathname can be relative to current directory or absolute. 713 650 * If the inode does not exist in the inode cache, it try to find the file on the mounted 714 651 * device, and creates an inode on a pseudo randomly selected cluster if found. 715 652 * It the requested file does not exist on device, it creates a new inode if the 716 * O_CREAT flag is set and return an error otherwise.717 ****************************************************************************************** 718 * @ cwd_xp : extended pointer on current working directory file descriptor.653 * O_CREAT flag is set, and return an error otherwise. 654 ****************************************************************************************** 655 * @ process : local pointer on local process descriptor copy. 719 656 * @ path : file pathname (absolute or relative to current directory). 720 * @ flags : defined above 657 * @ flags : defined above. 721 658 * @ mode : access rights (as defined by chmod) 722 659 * @ file_xp : [out] buffer for extended pointer on created remote file descriptor. … … 724 661 * @ return 0 if success / return non-zero if error. 725 662 *****************************************************************************************/ 726 error_t vfs_open( xptr_t cwd_xp,727 char * path,728 uint32_t flags,729 uint32_t mode,730 xptr_t * file_xp,731 uint32_t * file_id );663 error_t vfs_open( struct process_s * process, 664 char * path, 665 uint32_t flags, 666 uint32_t mode, 667 xptr_t * file_xp, 668 uint32_t * file_id ); 732 669 733 670 /****************************************************************************************** … … 735 672 * <file_xp> argument, and a - possibly distributed - user space <buffer>, taken into 736 673 * account the offset in <file_xp>. The transfer direction is defined by <to_buffer>. 737 * This function is called by the elf_load_process() function.674 * It is called by the sys_read() and sys_write() functions. 738 675 ****************************************************************************************** 739 676 * @ to_buffer : mapper -> buffer if true / buffer -> mapper if false. … … 741 678 * @ buffer : user space pointer on buffer (can be physically distributed). 742 679 * @ size : requested number of bytes from offset. 743 * @ returns 0f success / -1 if error.744 *****************************************************************************************/ 745 error_t vfs_user_move( bool_t to_buffer,746 747 748 680 * @ returns number of bytes actually moved if success / -1 if error. 681 *****************************************************************************************/ 682 int vfs_user_move( bool_t to_buffer, 683 xptr_t file_xp, 684 void * buffer, 685 uint32_t size ); 749 686 750 687 /****************************************************************************************** … … 752 689 * <file_xp> argument, and a - possibly remote - kernel <buffer_xp>, taken into 753 690 * account the offset in <file_xp>. The transfer direction is defined by <to_buffer>. 754 * This function is called by the system calls.691 * It is called by the elf_load_process() function. 755 692 ****************************************************************************************** 756 693 * @ to_buffer : mapper -> buffer if true / buffer -> mapper if false. … … 758 695 * @ buffer_xp : user space pointer on buffer (can be physically distributed). 759 696 * @ size : requested number of bytes from offset. 760 * @ returns number of bytes actually transfered/ -1 if error.697 * @ returns 0 if success / -1 if error. 761 698 *****************************************************************************************/ 762 699 error_t vfs_kernel_move( bool_t to_buffer, … … 814 751 ****************************************************************************************** 815 752 * @ file_xp : extended pointer on the file descriptor of the searched directory . 816 * @ k_ dirent : local pointer on the dirent_t structure in kernel space.753 * @ k_stat : local pointer on the stat structure in kernel space. 817 754 * @ returns 0 if success / -1 if error. 818 755 *****************************************************************************************/ 819 error_t vfs_stat( xptr_t file_xp,820 vfs_stat_t * k_stat );756 error_t vfs_stat( xptr_t file_xp, 757 struct stat * k_stat ); 821 758 822 759 /****************************************************************************************** … … 826 763 ****************************************************************************************** 827 764 * @ file_xp : extended pointer on the file descriptor of the searched directory . 828 * @ k_dirent : local pointer on the dirent _tstructure in kernel space.765 * @ k_dirent : local pointer on the dirent structure in kernel space. 829 766 * @ returns 0 if success / -1 if error. 830 767 *****************************************************************************************/ 831 error_t vfs_readdir( xptr_t file_xp,832 vfs_dirent_t * k_dirent );768 error_t vfs_readdir( xptr_t file_xp, 769 struct dirent * k_dirent ); 833 770 834 771 /****************************************************************************************** -
trunk/kernel/kern/chdev.c
r317 r407 25 25 #include <hal_types.h> 26 26 #include <hal_special.h> 27 #include <hal_irqmask.h> 27 28 #include <printk.h> 28 29 #include <boot_info.h> 29 30 #include <xlist.h> 30 31 #include <kmem.h> 32 #include <scheduler.h> 31 33 #include <thread.h> 32 34 #include <rpc.h> … … 37 39 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 38 40 41 #if CONFIG_READ_DEBUG 42 extern uint32_t enter_chdev_cmd; 43 extern uint32_t exit_chdev_cmd; 44 extern uint32_t enter_chdev_server; 45 extern uint32_t exit_chdev_server; 46 #endif 39 47 40 48 //////////////////////////////////////////// … … 105 113 } 106 114 107 //////////////////////////////////////////////// 108 void chdev_register_command( xptr_t chdev_xp, 109 thread_t * thread ) 110 { 111 thread_t * thread_ptr = CURRENT_THREAD; 115 ////////////////////////////////////////////////// 116 void chdev_register_command( xptr_t chdev_xp ) 117 { 118 thread_t * server_ptr; // local pointer on server thread associated to chdev 119 core_t * core_ptr; // local pointer on core running the server thread 120 uint32_t lid; // core running the server thread local index 121 xptr_t lock_xp; // extended pointer on lock protecting the chdev queue 122 uint32_t modified; // non zero if the server thread state was modified 123 uint32_t save_sr; // for critical section 124 125 thread_t * this = CURRENT_THREAD; 126 127 chdev_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) enter / cycle %d\n", 128 __FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type) , hal_time_stamp() ); 112 129 113 130 // get device descriptor cluster and local pointer … … 116 133 117 134 // build extended pointers on client thread xlist and device root 118 xptr_t xp_list = XPTR( local_cxy , &thread_ptr->wait_list ); 119 xptr_t xp_root = XPTR( chdev_cxy , &chdev_ptr->wait_root ); 120 121 // get lock protecting queue 122 remote_spinlock_lock( XPTR( chdev_cxy , &chdev_ptr->wait_lock ) ); 135 xptr_t list_xp = XPTR( local_cxy , &this->wait_list ); 136 xptr_t root_xp = XPTR( chdev_cxy , &chdev_ptr->wait_root ); 137 138 // get local pointer on server thread 139 server_ptr = (thread_t *)hal_remote_lpt( XPTR( chdev_cxy , &chdev_ptr->server) ); 140 141 chdev_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) / server_cxy %x / server_ptr %x / server_type %\n", 142 __FUNCTION__, local_cxy, this->core->lid, server_cxy, server_ptr, 143 thread_type_str( hal_remote_lw( XPTR( server_cxy , &server_ptr->type) ) ) ); 144 145 // build extended pointer on chdev lock protecting queue 146 lock_xp = XPTR( chdev_cxy , &chdev_ptr->wait_lock ); 147 148 // get local pointer on core running the server thread 149 core_ptr = (core_t *)hal_remote_lpt( XPTR( chdev_cxy , &server_ptr->core ) ); 150 151 // get core local index 152 lid = hal_remote_lw( XPTR( chdev_cxy , &core_ptr->lid ) ); 153 154 // enter critical section 155 hal_disable_irq( &save_sr ); 123 156 124 157 // register client thread in waiting queue 125 xlist_add_last( xp_root , xp_list ); 158 remote_spinlock_lock( lock_xp ); 159 xlist_add_last( root_xp , list_xp ); 160 remote_spinlock_unlock( lock_xp ); 126 161 127 162 // unblock server thread 128 thread_unblock( XPTR( chdev_cxy , &chdev_ptr->server ) , THREAD_BLOCKED_DEV_QUEUE ); 129 130 // release lock 131 remote_spinlock_unlock( XPTR( chdev_cxy , &chdev_ptr->wait_lock ) ); 132 133 // client thread goes to blocked state and deschedule 134 thread_block( thread_ptr , THREAD_BLOCKED_IO ); 135 sched_yield( NULL ); 163 modified = thread_unblock( XPTR( chdev_cxy , server_ptr ), THREAD_BLOCKED_DEV_QUEUE ); 164 165 // send IPI to core running the server thread 166 if( modified ) dev_pic_send_ipi( chdev_cxy , lid ); 167 168 // block client thread 169 assert( thread_can_yield( this ) , __FUNCTION__ , "illegal sched_yield\n" ); 170 171 chdev_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) deschedules / cycle %d\n", 172 __FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type) , hal_time_stamp() ); 173 174 thread_block( CURRENT_THREAD , THREAD_BLOCKED_IO ); 175 sched_yield(); 176 177 chdev_dmsg("\n[DBG] %s : core[%x,%d] (thread %s) resumes / cycle %d\n", 178 __FUNCTION__, local_cxy, this->core->lid, thread_type_str(this->type) , hal_time_stamp() ); 179 180 // exit critical section 181 hal_restore_irq( save_sr ); 136 182 137 183 } // end chdev_register_command() … … 143 189 cxy_t client_cxy; // cluster of client thread 144 190 thread_t * client_ptr; // local pointer on client thread 145 thread_t * server; // local pointer on thisthread191 thread_t * server; // local pointer on server thread 146 192 xptr_t root_xp; // extended pointer on device waiting queue root 193 xptr_t lock_xp; // extended pointer on lock ptotecting chdev queue 147 194 148 195 server = CURRENT_THREAD; 149 196 197 chdev_dmsg("\n[DBG] %s : enter / server = %x / chdev = %x / cycle %d\n", 198 __FUNCTION__ , server , chdev , hal_time_stamp() ); 199 150 200 root_xp = XPTR( local_cxy , &chdev->wait_root ); 151 152 // take the lock protecting the chdev waiting queue, before entering the 153 // infinite loop handling commands registered in this queue. 154 // In the loop, the lock is released during the handling of one command. 155 156 remote_spinlock_lock( XPTR( local_cxy , &chdev->wait_lock ) ); 157 201 lock_xp = XPTR( local_cxy , &chdev->wait_lock ); 202 203 // This infinite loop is executed by the DEV thread 204 // to handle commands registered in the chdev queue. 158 205 while( 1 ) 159 206 { 207 // get the lock protecting the waiting queue 208 remote_spinlock_lock( lock_xp ); 209 160 210 // check waiting queue state 161 if( xlist_is_empty( root_xp ) ) // block and deschedule ifwaiting queue empty211 if( xlist_is_empty( root_xp ) ) // waiting queue empty 162 212 { 163 213 // release lock 164 remote_spinlock_unlock( XPTR( local_cxy , &chdev->wait_lock ) ); 214 remote_spinlock_unlock( lock_xp ); 215 216 chdev_dmsg("\n[DBG] %s : thread %x deschedule /cycle %d\n", 217 __FUNCTION__ , server , hal_time_stamp() ); 165 218 166 219 // block and deschedule 167 220 thread_block( server , THREAD_BLOCKED_DEV_QUEUE ); 168 sched_yield( NULL ); 221 sched_yield(); 222 223 chdev_dmsg("\n[DBG] %s : thread %x resume /cycle %d\n", 224 __FUNCTION__ , server , hal_time_stamp() ); 225 169 226 } 170 else 227 else // waiting queue not empty 171 228 { 229 230 #if CONFIG_READ_DEBUG 231 enter_chdev_server = hal_time_stamp(); 232 #endif 172 233 // release lock 173 remote_spinlock_unlock( XPTR( local_cxy , &chdev->wait_lock ) ); 234 remote_spinlock_unlock( lock_xp ); 235 236 // get extended pointer on first client thread 237 client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list ); 238 239 // get client thread cluster, local pointer, and identifier 240 client_cxy = GET_CXY( client_xp ); 241 client_ptr = (thread_t *)GET_PTR( client_xp ); 242 243 // call driver command function to execute I/O operation 244 chdev->cmd( client_xp ); 245 246 // remove the client thread from waiting queue 247 remote_spinlock_lock( lock_xp ); 248 xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) ); 249 remote_spinlock_unlock( lock_xp ); 250 251 chdev_dmsg("\n[DBG] %s : thread %x complete operation for client %x / cycle %d\n", 252 __FUNCTION__ , server , client_ptr , hal_time_stamp() ); 253 254 #if CONFIG_READ_DEBUG 255 exit_chdev_server = hal_time_stamp(); 256 #endif 257 174 258 } 175 176 // get extended pointer on first client thread177 client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list );178 179 // call driver command function to execute I/O operation180 chdev->cmd( client_xp );181 182 // get client thread cluster and local pointer183 client_cxy = GET_CXY( client_xp );184 client_ptr = (thread_t *)GET_PTR( client_xp );185 186 // take the lock, and remove the client thread from waiting queue187 remote_spinlock_lock( XPTR( local_cxy , &chdev->wait_lock ) );188 xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) );189 190 259 } // end while 191 192 260 } // end chdev_sequencial_server() 193 261 … … 197 265 cxy_t iob_cxy = GET_CXY( chdev_dir.iob ); 198 266 chdev_t * iob_ptr = (chdev_t *)GET_PTR( chdev_dir.iob ); 199 xptr_t iob_base =hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) );267 uint32_t iob_base = (uint32_t)hal_remote_lwd( XPTR( iob_cxy , &iob_ptr->base ) ); 200 268 201 269 cxy_t pic_cxy = GET_CXY( chdev_dir.pic ); 202 270 chdev_t * pic_ptr = (chdev_t *)GET_PTR( chdev_dir.pic ); 203 xptr_t pic_base = hal_remote_lwd( XPTR( pic_cxy , &pic_ptr->base ) ); 204 205 cxy_t txt0_cxy = GET_CXY( chdev_dir.txt[0] ); 206 chdev_t * txt0_ptr = (chdev_t *)GET_PTR( chdev_dir.txt[0] ); 207 xptr_t txt0_base = hal_remote_lwd( XPTR( txt0_cxy , &txt0_ptr->base ) ); 208 209 cxy_t txt1_cxy = GET_CXY( chdev_dir.txt[1] ); 210 chdev_t * txt1_ptr = (chdev_t *)GET_PTR( chdev_dir.txt[1] ); 211 xptr_t txt1_base = hal_remote_lwd( XPTR( txt1_cxy , &txt1_ptr->base ) ); 212 213 cxy_t txt2_cxy = GET_CXY( chdev_dir.txt[2] ); 214 chdev_t * txt2_ptr = (chdev_t *)GET_PTR( chdev_dir.txt[2] ); 215 xptr_t txt2_base = hal_remote_lwd( XPTR( txt2_cxy , &txt2_ptr->base ) ); 271 uint32_t pic_base = (uint32_t)hal_remote_lwd( XPTR( pic_cxy , &pic_ptr->base ) ); 272 273 cxy_t txt0_tx_cxy = GET_CXY( chdev_dir.txt_tx[0] ); 274 chdev_t * txt0_tx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_tx[0] ); 275 uint32_t txt0_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt0_tx_cxy , &txt0_tx_ptr->base ) ); 276 277 cxy_t txt0_rx_cxy = GET_CXY( chdev_dir.txt_rx[0] ); 278 chdev_t * txt0_rx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_rx[0] ); 279 uint32_t txt0_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt0_rx_cxy , &txt0_rx_ptr->base ) ); 280 281 cxy_t txt1_tx_cxy = GET_CXY( chdev_dir.txt_tx[1] ); 282 chdev_t * txt1_tx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_tx[1] ); 283 uint32_t txt1_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt1_tx_cxy , &txt1_tx_ptr->base ) ); 284 285 cxy_t txt1_rx_cxy = GET_CXY( chdev_dir.txt_rx[1] ); 286 chdev_t * txt1_rx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_rx[1] ); 287 uint32_t txt1_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt1_rx_cxy , &txt1_rx_ptr->base ) ); 288 289 cxy_t txt2_tx_cxy = GET_CXY( chdev_dir.txt_tx[2] ); 290 chdev_t * txt2_tx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_tx[2] ); 291 uint32_t txt2_tx_base = (uint32_t)hal_remote_lwd( XPTR( txt2_tx_cxy , &txt2_tx_ptr->base ) ); 292 293 cxy_t txt2_rx_cxy = GET_CXY( chdev_dir.txt_rx[2] ); 294 chdev_t * txt2_rx_ptr = (chdev_t *)GET_PTR( chdev_dir.txt_rx[2] ); 295 uint32_t txt2_rx_base = (uint32_t)hal_remote_lwd( XPTR( txt2_rx_cxy , &txt2_rx_ptr->base ) ); 216 296 217 297 cxy_t ioc_cxy = GET_CXY( chdev_dir.ioc[0] ); 218 298 chdev_t * ioc_ptr = (chdev_t *)GET_PTR( chdev_dir.ioc[0] ); 219 xptr_t ioc_base =hal_remote_lwd( XPTR( ioc_cxy , &ioc_ptr->base ) );299 uint32_t ioc_base = (uint32_t)hal_remote_lwd( XPTR( ioc_cxy , &ioc_ptr->base ) ); 220 300 221 301 cxy_t fbf_cxy = GET_CXY( chdev_dir.fbf[0] ); 222 302 chdev_t * fbf_ptr = (chdev_t *)GET_PTR( chdev_dir.fbf[0] ); 223 xptr_t fbf_base =hal_remote_lwd( XPTR( fbf_cxy , &fbf_ptr->base ) );224 225 cxy_t nic _rx_cxy = GET_CXY( chdev_dir.nic_rx[0] );226 chdev_t * nic _rx_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_rx[0] );227 xptr_t nic_rx_base = hal_remote_lwd( XPTR( nic_rx_cxy , &nic_rx_ptr->base ) );228 229 cxy_t nic _tx_cxy = GET_CXY( chdev_dir.nic_tx[0] );230 chdev_t * nic _tx_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_tx[0] );231 xptr_t nic_tx_base = hal_remote_lwd( XPTR( nic_tx_cxy , &nic_tx_ptr->base ) );303 uint32_t fbf_base = (uint32_t)hal_remote_lwd( XPTR( fbf_cxy , &fbf_ptr->base ) ); 304 305 cxy_t nic0_rx_cxy = GET_CXY( chdev_dir.nic_rx[0] ); 306 chdev_t * nic0_rx_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_rx[0] ); 307 uint32_t nic0_rx_base = (uint32_t)hal_remote_lwd( XPTR( nic0_rx_cxy , &nic0_rx_ptr->base ) ); 308 309 cxy_t nic0_tx_cxy = GET_CXY( chdev_dir.nic_tx[0] ); 310 chdev_t * nic0_tx_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_tx[0] ); 311 uint32_t nic0_tx_base = (uint32_t)hal_remote_lwd( XPTR( nic0_tx_cxy , &nic0_tx_ptr->base ) ); 232 312 233 313 printk("\n***** external chdev directory in cluster %x\n" 234 " - iob = %l / base = %l\n" 235 " - pic = %l / base = %l\n" 236 " - txt[0] = %l / base = %l\n" 237 " - txt[1] = %l / base = %l\n" 238 " - txt[2] = %l / base = %l\n" 239 " - ioc[0] = %l / base = %l\n" 240 " - fbf[0] = %l / base = %l\n" 241 " - nic_rx[0] = %l / base = %l\n" 242 " - nic_tx[0] = %l / base = %l\n", 314 " - iob : cxy = %X / ptr = %X / base = %X\n" 315 " - pic : cxy = %X / ptr = %X / base = %X\n" 316 " - ioc : cxy = %X / ptr = %X / base = %X\n" 317 " - fbf : cxy = %X / ptr = %X / base = %X\n" 318 " - txt_rx[0] : cxy = %X / ptr = %X / base = %X\n" 319 " - txt_tx[0] : cxy = %X / ptr = %X / base = %X\n" 320 " - txt_rx[1] : cxy = %X / ptr = %X / base = %X\n" 321 " - txt_tx[1] : cxy = %X / ptr = %X / base = %X\n" 322 " - txt_rx[2] : cxy = %X / ptr = %X / base = %X\n" 323 " - txt_tx[2] : cxy = %X / ptr = %X / base = %X\n" 324 " - nic_rx[0] : cxy = %X / ptr = %X / base = %X\n" 325 " - nic_tx[0] : cxy = %X / ptr = %X / base = %X\n", 243 326 local_cxy, 244 chdev_dir.iob, iob_base, 245 chdev_dir.pic, pic_base, 246 chdev_dir.txt[0], txt0_base, 247 chdev_dir.txt[1], txt1_base, 248 chdev_dir.txt[2], txt2_base, 249 chdev_dir.ioc[0], ioc_base, 250 chdev_dir.fbf[0], fbf_base, 251 chdev_dir.nic_rx[0], nic_rx_base, 252 chdev_dir.nic_tx[0], nic_tx_base ); 327 iob_cxy , iob_ptr , iob_base , 328 pic_cxy , pic_ptr , pic_base , 329 ioc_cxy , ioc_ptr , ioc_base , 330 fbf_cxy , fbf_ptr , fbf_base , 331 txt0_rx_cxy , txt0_rx_ptr , txt0_rx_base , 332 txt0_tx_cxy , txt0_tx_ptr , txt0_tx_base , 333 txt1_rx_cxy , txt1_rx_ptr , txt1_rx_base , 334 txt1_tx_cxy , txt1_tx_ptr , txt1_tx_base , 335 txt2_rx_cxy , txt2_rx_ptr , txt2_rx_base , 336 txt2_tx_cxy , txt2_tx_ptr , txt2_tx_base , 337 nic0_rx_cxy , nic0_rx_ptr , nic0_rx_base , 338 nic0_tx_cxy , nic0_tx_ptr , nic0_tx_base ); 253 339 254 340 } // end chdev_dir_display() -
trunk/kernel/kern/chdev.h
r346 r407 66 66 67 67 /****************************************************************************************** 68 * This define the generic prototypes for the t wofunctions that must be defined69 * by alldrivers implementing a generic device:70 * - "cmd" : start a nI/O operation.68 * This define the generic prototypes for the three functions that must be defined 69 * by the drivers implementing a generic device: 70 * - "cmd" : start a blocking I/O operation. 71 71 * - "isr" : complete an I/O operation. 72 * The "cmd" and "isr" are registered in the generic chdev descriptor at kernel init, 73 * and are called to start and complete an I/O operation. 72 * - "aux" : not for all drivers (implement special functions) 73 * The "cmd", "isr", and "aux" driver functions are registered in the generic chdev 74 * descriptor at kernel init, and are called to start and complete an I/O operation. 74 75 *****************************************************************************************/ 75 76 … … 77 78 typedef void (dev_cmd_t) ( xptr_t thread ); 78 79 typedef void (dev_isr_t) ( struct chdev_s * dev ); 80 typedef void (dev_aux_t) ( void * args ); 79 81 80 82 /****************************************************************************************** … … 121 123 uint32_t impl; /*! peripheral inplementation subtype */ 122 124 uint32_t channel; /*! channel index */ 123 bool_t is_rx; /*! relevant for NIC peripheral channels only*/125 bool_t is_rx; /*! relevant for NIC and TXT peripherals */ 124 126 xptr_t base; /*! extended pointer on channel device segment */ 125 127 char name[16]; /*! name (required by DEVFS) */ 126 128 127 dev_cmd_t * cmd; /*! local pointer on driver command function */ 128 dev_isr_t * isr; /*! local pointer on driver ISR function */ 129 dev_cmd_t * cmd; /*! local pointer on driver CMD function */ 130 dev_isr_t * isr; /*! local pointer on driver ISR function */ 131 dev_aux_t * aux; /*! local pointer on driver AUX function */ 132 129 133 struct thread_s * server; /*! local pointer on associated server thread */ 130 134 … … 165 169 xptr_t pic; // external / single channel / shared 166 170 167 xptr_t txt[CONFIG_MAX_TXT_CHANNELS]; // external / multi-channels / shared168 171 xptr_t ioc[CONFIG_MAX_IOC_CHANNELS]; // external / multi-channels / shared 169 172 xptr_t fbf[CONFIG_MAX_FBF_CHANNELS]; // external / multi-channels / shared 173 xptr_t txt_rx[CONFIG_MAX_TXT_CHANNELS]; // external / multi-channels / shared 174 xptr_t txt_tx[CONFIG_MAX_TXT_CHANNELS]; // external / multi-channels / shared 170 175 xptr_t nic_rx[CONFIG_MAX_NIC_CHANNELS]; // external / multi-channels / shared 171 176 xptr_t nic_tx[CONFIG_MAX_NIC_CHANNELS]; // external / multi-channels / shared … … 211 216 212 217 /****************************************************************************************** 213 * This function registers a local clientthread in the waiting queue of a remote218 * This function registers the calling thread in the waiting queue of a remote 214 219 * chdev descriptor, activates (i.e. unblock) the server thread associated to chdev, 215 220 * and blocks itself on the THREAD_BLOCKED_IO condition. 216 221 ****************************************************************************************** 217 222 * @ chdev_xp : extended pointer on remote chdev descriptor. 218 * @ thread : local pointer on client thread. 219 *****************************************************************************************/ 220 void chdev_register_command( xptr_t chdev_xp, 221 struct thread_s * thread ); 223 *****************************************************************************************/ 224 void chdev_register_command( xptr_t chdev_xp ); 222 225 223 226 /****************************************************************************************** -
trunk/kernel/kern/cluster.c
r406 r407 29 29 #include <hal_special.h> 30 30 #include <hal_ppm.h> 31 #include <remote_fifo.h> 31 32 #include <printk.h> 32 33 #include <errno.h> … … 77 78 // initialize cluster local parameters 78 79 cluster->cores_nr = info->cores_nr; 79 cluster->cores_in_kernel = 0;80 80 81 81 // initialize the lock protecting the embedded kcm allocator 82 82 spinlock_init( &cluster->kcm_lock ); 83 83 84 cluster_dmsg("\n[DMSG] %s for cluster %x enters\n",85 84 cluster_dmsg("\n[DBG] %s for cluster %x enters\n", 85 __FUNCTION__ , local_cxy ); 86 86 87 87 // initialises DQDT … … 102 102 } 103 103 104 cluster_dmsg("\n[DMSG] %s : PPM initialized in cluster %x at cycle %d\n",105 104 cluster_dmsg("\n[DBG] %s : PPM initialized in cluster %x at cycle %d\n", 105 __FUNCTION__ , local_cxy , hal_get_cycles() ); 106 106 107 107 // initialises embedded KHM 108 108 khm_init( &cluster->khm ); 109 109 110 cluster_dmsg("\n[D MSG] %s : KHM initialized in cluster %x at cycle %d\n",110 cluster_dmsg("\n[DBG] %s : KHM initialized in cluster %x at cycle %d\n", 111 111 __FUNCTION__ , local_cxy , hal_get_cycles() ); 112 112 … … 114 114 kcm_init( &cluster->kcm , KMEM_KCM ); 115 115 116 cluster_dmsg("\n[D MSG] %s : KCM initialized in cluster %x at cycle %d\n",116 cluster_dmsg("\n[DBG] %s : KCM initialized in cluster %x at cycle %d\n", 117 117 __FUNCTION__ , local_cxy , hal_get_cycles() ); 118 118 … … 125 125 } 126 126 127 cluster_dmsg("\n[DMSG] %s : cores initialized in cluster %x at cycle %d\n",128 127 cluster_dmsg("\n[DBG] %s : cores initialized in cluster %x at cycle %d\n", 128 __FUNCTION__ , local_cxy , hal_get_cycles() ); 129 129 130 130 // initialises RPC fifo 131 rpc_fifo_init( &cluster->rpc_fifo );131 local_fifo_init( &cluster->rpc_fifo ); 132 132 cluster->rpc_threads = 0; 133 133 134 cluster_dmsg("\n[DMSG] %s : RPC fifo inialized in cluster %x at cycle %d\n",135 134 cluster_dmsg("\n[DBG] %s : RPC fifo inialized in cluster %x at cycle %d\n", 135 __FUNCTION__ , local_cxy , hal_get_cycles() ); 136 136 137 137 // initialise pref_tbl[] in process manager … … 157 157 } 158 158 159 cluster_dmsg("\n[DMSG] %s Process Manager initialized in cluster %x at cycle %d\n",160 159 cluster_dmsg("\n[DBG] %s Process Manager initialized in cluster %x at cycle %d\n", 160 __FUNCTION__ , local_cxy , hal_get_cycles() ); 161 161 162 162 hal_fence(); … … 184 184 // Cores related functions 185 185 //////////////////////////////////////////////////////////////////////////////////// 186 187 ////////////////////////////////188 void cluster_core_kernel_enter()189 {190 cluster_t * cluster = LOCAL_CLUSTER;191 hal_atomic_add( &cluster->cores_in_kernel , 1 );192 }193 194 ///////////////////////////////195 void cluster_core_kernel_exit()196 {197 cluster_t * cluster = LOCAL_CLUSTER;198 hal_atomic_add( &cluster->cores_in_kernel , -1 );199 }200 186 201 187 ///////////////////////////////// … … 353 339 void cluster_process_local_link( process_t * process ) 354 340 { 341 uint32_t irq_state; 355 342 pmgr_t * pm = &LOCAL_CLUSTER->pmgr; 356 343 357 344 // get lock protecting the process manager local list 358 remote_spinlock_lock ( XPTR( local_cxy , &pm->local_lock ));345 remote_spinlock_lock_busy( XPTR( local_cxy , &pm->local_lock ) , & irq_state ); 359 346 360 347 xlist_add_first( XPTR( local_cxy , &pm->local_root ), … … 363 350 364 351 // release lock protecting the process manager local list 365 remote_spinlock_unlock ( XPTR( local_cxy , &pm->local_lock ));352 remote_spinlock_unlock_busy( XPTR( local_cxy , &pm->local_lock ) , irq_state ); 366 353 } 367 354 … … 369 356 void cluster_process_local_unlink( process_t * process ) 370 357 { 358 uint32_t irq_state; 371 359 pmgr_t * pm = &LOCAL_CLUSTER->pmgr; 372 360 373 361 // get lock protecting the process manager local list 374 remote_spinlock_lock ( XPTR( local_cxy , &pm->local_lock ));362 remote_spinlock_lock_busy( XPTR( local_cxy , &pm->local_lock ) , &irq_state ); 375 363 376 364 xlist_unlink( XPTR( local_cxy , &process->local_list ) ); … … 378 366 379 367 // release lock protecting the process manager local list 380 remote_spinlock_unlock ( XPTR( local_cxy , &pm->local_lock ));368 remote_spinlock_unlock_busy( XPTR( local_cxy , &pm->local_lock ) , irq_state ); 381 369 } 382 370 … … 384 372 void cluster_process_copies_link( process_t * process ) 385 373 { 374 uint32_t irq_state; 386 375 pmgr_t * pm = &LOCAL_CLUSTER->pmgr; 387 376 … … 401 390 402 391 // get lock protecting copies_list[lpid] 403 remote_spinlock_lock ( copies_lock);392 remote_spinlock_lock_busy( copies_lock , &irq_state ); 404 393 405 394 xlist_add_first( copies_root , copies_entry ); … … 407 396 408 397 // release lock protecting copies_list[lpid] 409 remote_spinlock_unlock ( copies_lock);398 remote_spinlock_unlock_busy( copies_lock , irq_state ); 410 399 } 411 400 … … 413 402 void cluster_process_copies_unlink( process_t * process ) 414 403 { 404 uint32_t irq_state; 415 405 pmgr_t * pm = &LOCAL_CLUSTER->pmgr; 416 406 … … 427 417 428 418 // get lock protecting copies_list[lpid] 429 remote_spinlock_lock ( copies_lock);419 remote_spinlock_lock_busy( copies_lock , &irq_state ); 430 420 431 421 xlist_unlink( copies_entry ); … … 433 423 434 424 // release lock protecting copies_list[lpid] 435 remote_spinlock_unlock ( copies_lock);425 remote_spinlock_unlock_busy( copies_lock , irq_state ); 436 426 } 437 427 -
trunk/kernel/kern/cluster.h
r279 r407 108 108 109 109 // local parameters 110 uint32_t cores_nr; /*! number of cores in cluster */ 111 uint32_t cores_in_kernel; /*! number of cores currently in kernel mode */ 112 110 uint32_t cores_nr; /*! actual number of cores in cluster */ 113 111 uint32_t ram_size; /*! physical memory size */ 114 112 uint32_t ram_base; /*! physical memory base (local address) */ … … 125 123 126 124 // RPC 127 r pc_fifo_t rpc_fifo; /*! RPC fifo*/128 uint32_t rpc_threads; /*! current number of RPC threads 125 remote_fifo_t rpc_fifo; /*! RPC fifo (one per cluster) */ 126 uint32_t rpc_threads; /*! current number of RPC threads in cluster */ 129 127 130 128 // DQDT … … 173 171 174 172 /****************************************************************************************** 175 * This function checks the validity of a cluster identifier. TODO useful ??? [AG]173 * This function checks the validity of a cluster identifier. 176 174 ****************************************************************************************** 177 175 * @ cxy : cluster identifier to be checked. … … 179 177 *****************************************************************************************/ 180 178 bool_t cluster_is_undefined( cxy_t cxy ); 181 182 /******************************************************************************************183 * This function register sysfs information in cluster TODO ??? [AG]184 *****************************************************************************************/185 void cluster_sysfs_register();186 179 187 180 -
trunk/kernel/kern/core.c
r406 r407 107 107 ticks = core->ticks_nr++; 108 108 109 // handle pending alarms TODO ??? [AG] 110 // alarm_clock( &core->alarm_mgr , ticks);109 // handle signals for all threads executing on this core 110 sched_handle_signals( core ); 111 111 112 112 // handle scheduler 113 if( (ticks % CONFIG_SCHED_TICKS_PER_QUANTUM) == 0 ) sched_yield( NULL);113 if( (ticks % CONFIG_SCHED_TICKS_PER_QUANTUM) == 0 ) sched_yield(); 114 114 115 115 // update DQDT -
trunk/kernel/kern/do_syscall.c
r406 r407 31 31 32 32 ///////////////////////////////////////////////////////////////////////////////////////////// 33 // This ƒonction should never be called... 33 34 ///////////////////////////////////////////////////////////////////////////////////////////// 34 static in line int sys_undefined()35 static int sys_undefined() 35 36 { 36 37 panic("undefined system call"); … … 40 41 ///////////////////////////////////////////////////////////////////////////////////////////// 41 42 // This array of pointers define the kernel functions implementing the syscalls. 42 // It must be kept consistent with the enum in syscalls.h43 // It must be kept consistent with the enum in "shared_syscalls.h" file. 43 44 ///////////////////////////////////////////////////////////////////////////////////////////// 44 45 … … 48 49 { 49 50 sys_thread_exit, // 0 50 sys_ mmap, // 151 sys_thread_yield, // 1 51 52 sys_thread_create, // 2 52 53 sys_thread_join, // 3 53 54 sys_thread_detach, // 4 54 sys_ thread_yield,// 555 sys_undefined, // 5 55 56 sys_sem, // 6 56 57 sys_condvar, // 7 57 58 sys_barrier, // 8 58 59 sys_mutex, // 9 59 sys_thread_sleep, // 10 60 sys_thread_wakeup, // 11 60 61 sys_undefined, // 10 62 sys_munmap, // 11 61 63 sys_open, // 12 62 sys_ creat,// 1364 sys_mmap, // 13 63 65 sys_read, // 14 64 66 sys_write, // 15 … … 67 69 sys_unlink, // 18 68 70 sys_pipe, // 19 71 69 72 sys_chdir, // 20 70 73 sys_mkdir, // 21 … … 74 77 sys_closedir, // 25 75 78 sys_getcwd, // 26 76 sys_ clock, // 2779 sys_undefined, // 27 77 80 sys_alarm, // 28 78 81 sys_rmdir, // 29 82 79 83 sys_utls, // 30 80 84 sys_chmod, // 31 … … 87 91 sys_stat, // 38 88 92 sys_trace, // 39 93 94 sys_get_config, // 40 95 sys_get_core, // 41 96 sys_get_cycle, // 42 97 sys_get_sched, // 43 98 sys_panic, // 44 99 sys_thread_sleep, // 45 100 sys_thread_wakeup, // 46 89 101 }; 90 102 … … 102 114 thread_user_time_update( this ); 103 115 104 // enable IRQs116 // enable interrupts 105 117 hal_enable_irq( NULL ); 106 118 … … 116 128 } 117 129 118 syscall_dmsg("\n[DMSG] %s : pid = %x / trdid = %x / service #%d\n" 119 " arg0 = %x / arg1 = %x / arg2 = %x / arg3 = %x\n", 120 __FUNCTION__ , this->process->pid , this->trdid , service_num , 121 arg0 , arg1 , arg2 , arg3 ); 130 #if( CONFIG_SYSCALL_DEBUG & 0x1) 131 printk("\n[DBG] %s : pid = %x / trdid = %x / service #%d\n" 132 " arg0 = %x / arg1 = %x / arg2 = %x / arg3 = %x\n", 133 __FUNCTION__ , this->process->pid , this->trdid , service_num , arg0 , arg1 , arg2 , arg3 ); 134 #endif 122 135 123 136 // reset errno … … 127 140 error = syscall_tbl[service_num] ( arg0 , arg1 , arg2 , arg3 ); 128 141 129 // handle pending signals for the calling thread 130 thread_signals_handle( this ); 131 132 // disable IRQs 142 // disable interrupt 133 143 hal_disable_irq( NULL ); 134 144 -
trunk/kernel/kern/do_syscall.h
r16 r407 1 1 /* 2 * do_syscall.h - kernel service numbers asked by userland2 * do_syscall.h - generic syscall handler. 3 3 * 4 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) … … 32 32 /******************************************************************************************** 33 33 * This function calls the kernel function defined by the <service_num> argument. 34 * The possible values for servic_num are defined in the syscalls/syscalls.h file. 34 35 ******************************************************************************************** 35 36 * @ this : pointer on calling thread descriptor -
trunk/kernel/kern/kernel_init.c
r406 r407 32 32 #include <barrier.h> 33 33 #include <remote_barrier.h> 34 #include <remote_fifo.h> 34 35 #include <core.h> 35 36 #include <list.h> … … 85 86 cluster_t cluster_manager CONFIG_CACHE_LINE_ALIGNED; 86 87 87 // This variable defines the TXT0 kernel terminal 88 // This variable defines the TXT0 kernel terminal (TX only) 88 89 __attribute__((section(".kdata"))) 89 90 chdev_t txt0_chdev CONFIG_CACHE_LINE_ALIGNED; … … 121 122 vfs_ctx_t fs_context[FS_TYPES_NR] CONFIG_CACHE_LINE_ALIGNED; 122 123 124 // These variables are used by the sched_yield function to save SR value 125 __attribute__((section(".kdata"))) 126 uint32_t switch_save_sr[CONFIG_MAX_LOCAL_CORES] CONFIG_CACHE_LINE_ALIGNED; 127 128 #if CONFIG_READ_DEBUG 129 uint32_t enter_sys_read; 130 uint32_t exit_sys_read; 131 132 uint32_t enter_devfs_move; 133 uint32_t exit_devfs_move; 134 135 uint32_t enter_txt_read; 136 uint32_t exit_txt_read; 137 138 uint32_t enter_chdev_cmd; 139 uint32_t exit_chdev_cmd; 140 141 uint32_t enter_chdev_server; 142 uint32_t exit_chdev_server; 143 144 uint32_t enter_tty_cmd; 145 uint32_t exit_tty_cmd; 146 147 uint32_t enter_tty_isr; 148 uint32_t exit_tty_isr; 149 #endif 123 150 124 151 /////////////////////////////////////////////////////////////////////////////////////////// … … 137 164 " /_/ \\_\\ |______| |_| |_| \\_____/ |______/ |_| |_| |_| \\_\\ |_| |_| \n" 138 165 "\n\n\t\t Advanced Locality Management Operating System / Multi Kernel Hybrid\n" 139 "\n\n\t\t\t Version 0.0 / %d cluster(s) / %d core(s) per cluster\n\n", nclusters , ncores ); 166 "\n\n\t\t Version 0.0 / %d cluster(s) / %d core(s) per cluster / cycle %d\n\n", 167 nclusters , ncores , hal_time_stamp() ); 140 168 } 141 169 … … 201 229 { 202 230 cxy_t cxy = (x<<info->y_width) + y; 203 hal_remote_swd( XPTR( cxy , &chdev_dir.txt [0] ) ,231 hal_remote_swd( XPTR( cxy , &chdev_dir.txt_tx[0] ) , 204 232 XPTR( local_cxy , &txt0_chdev ) ); 205 233 } … … 273 301 } 274 302 275 #if( CONFIG_KINIT_DEBUG > 1 ) 276 printk("\n[DMSG] %s : created MMC in cluster %x / chdev = %x\n", 277 __FUNCTION__ , channel , local_cxy , chdev_ptr ); 303 #if( CONFIG_KINIT_DEBUG & 0x1 ) 304 if( hal_time_stamp() > CONFIG_KINIT_DEBUG ) 305 printk("\n[DBG] %s : created MMC in cluster %x / chdev = %x\n", 306 __FUNCTION__ , local_cxy , chdev_ptr ); 278 307 #endif 279 308 } … … 301 330 chdev_dir.dma[channel] = XPTR( local_cxy , chdev_ptr ); 302 331 303 #if( CONFIG_KINIT_DEBUG > 1 ) 304 printk("\n[DMSG] %s : created DMA[%d] in cluster %x / chdev = %x\n", 332 #if( CONFIG_KINIT_DEBUG & 0x1 ) 333 if( hal_time_stamp() > CONFIG_KINIT_DEBUG ) 334 printk("\n[DBG] %s : created DMA[%d] in cluster %x / chdev = %x\n", 305 335 __FUNCTION__ , channel , local_cxy , chdev_ptr ); 306 336 #endif … … 355 385 impl = IMPL_FROM_TYPE( dev_tbl[i].type ); 356 386 357 // There is one chdev per direction for NIC 358 if (func == DEV_FUNC_NIC) directions = 2;359 else directions = 1;387 // There is one chdev per direction for NIC and for TXT 388 if((func == DEV_FUNC_NIC) || (func == DEV_FUNC_TXT)) directions = 2; 389 else directions = 1; 360 390 361 391 // The TXT0 chdev has already been created … … 363 393 else first_channel = 0; 364 394 365 // do nothing for RO , that does not require a device descriptor.395 // do nothing for ROM, that does not require a device descriptor. 366 396 if( func == DEV_FUNC_ROM ) continue; 367 397 … … 394 424 395 425 // allocate and initialize a local chdev 396 // iflocal cluster matches target cluster426 // when local cluster matches target cluster 397 427 if( target_cxy == local_cxy ) 398 428 { … … 420 450 if(func==DEV_FUNC_IOB ) entry = &chdev_dir.iob; 421 451 if(func==DEV_FUNC_IOC ) entry = &chdev_dir.ioc[channel]; 422 if(func==DEV_FUNC_TXT ) entry = &chdev_dir.txt[channel];423 452 if(func==DEV_FUNC_FBF ) entry = &chdev_dir.fbf[channel]; 453 if((func==DEV_FUNC_TXT) && (rx==0)) entry = &chdev_dir.txt_tx[channel]; 454 if((func==DEV_FUNC_TXT) && (rx==1)) entry = &chdev_dir.txt_rx[channel]; 424 455 if((func==DEV_FUNC_NIC) && (rx==0)) entry = &chdev_dir.nic_tx[channel]; 425 456 if((func==DEV_FUNC_NIC) && (rx==1)) entry = &chdev_dir.nic_rx[channel]; … … 435 466 } 436 467 437 #if( CONFIG_KINIT_DEBUG > 1 ) 438 printk("\n[DMSG] %s : create chdev %s[%d] in cluster %x / chdev = %x\n", 439 __FUNCTION__ , chdev_func_str( func ), channel , local_cxy , chdev ); 468 #if( CONFIG_KINIT_DEBUG & 0x1 ) 469 if( hal_time_stamp() > CONFIG_KINIT_DEBUG ) 470 printk("\n[DBG] %s : create chdev %s / channel = %d / rx = %d / cluster %x / chdev = %x\n", 471 __FUNCTION__ , chdev_func_str( func ), channel , rx , local_cxy , chdev ); 440 472 #endif 441 473 } // end if match … … 451 483 /////////////////////////////////////////////////////////////////////////////////////////// 452 484 // This function is called by CP0 in cluster 0 to allocate memory and initialize the PIC 453 // device, namely the informations attached to the external IOPIC controller. 485 // device, namely the informations attached to the external IOPIC controller, that 486 // must be replicated in all clusters (struct iopic_input). 454 487 // This initialisation must be done before other devices initialisation because the IRQ 455 // routing infrastructure is required for internal and external devices initialisation.488 // routing infrastructure is required for both internal and external devices init. 456 489 /////////////////////////////////////////////////////////////////////////////////////////// 457 490 // @ info : pointer on the local boot-info structure. … … 490 523 assert( found , __FUNCTION__ , "PIC device not found\n" ); 491 524 492 // allocate and initialize the PIC chdev in local cluster493 chdev = chdev_create( func,525 // allocate and initialize the PIC chdev in cluster 0 526 chdev = chdev_create( DEV_FUNC_PIC, 494 527 impl, 495 528 0, // channel … … 502 535 dev_pic_init( chdev ); 503 536 504 // register extended pointer on PIC chdev in "chdev_dir" array in all clusters 537 // register, in all clusters, the extended pointer 538 // on PIC chdev in "chdev_dir" array 505 539 xptr_t * entry = &chdev_dir.pic; 506 540 … … 515 549 } 516 550 517 // initialize the "iopic_input" structure551 // initialize, in all clusters, the "iopic_input" structure 518 552 // defining how external IRQs are connected to IOPIC 519 uint32_t id; 520 uint8_t valid; 521 uint32_t type; 522 uint8_t channel; 523 uint8_t is_rx; 553 554 // register default value for unused inputs 555 for( x = 0 ; x < info->x_size ; x++ ) 556 { 557 for( y = 0 ; y < info->y_size ; y++ ) 558 { 559 cxy_t cxy = (x<<info->y_width) + y; 560 hal_remote_memset( XPTR( cxy , &iopic_input ) , 0xFF , sizeof(iopic_input_t) ); 561 } 562 } 563 564 // register input IRQ index for valid inputs 565 uint32_t id; // input IRQ index 566 uint8_t valid; // input IRQ is connected 567 uint32_t type; // source device type 568 uint8_t channel; // source device channel 569 uint8_t is_rx; // source device direction 570 uint32_t * ptr; // local pointer on one field in iopic_input stucture 524 571 525 572 for( id = 0 ; id < CONFIG_MAX_EXTERNAL_IRQS ; id++ ) … … 529 576 channel = dev_tbl[i].irq[id].channel; 530 577 is_rx = dev_tbl[i].irq[id].is_rx; 531 532 if( valid ) // only valid inputs are registered 533 { 534 uint32_t * index; // local pointer on one entry 535 uint16_t func = FUNC_FROM_TYPE( type ); 536 537 if ( func == DEV_FUNC_TXT ) 538 index = &iopic_input.txt[channel]; 539 else if( func == DEV_FUNC_IOC ) 540 index = &iopic_input.ioc[channel]; 541 else if( (func == DEV_FUNC_NIC) && (is_rx == 0) ) 542 index = &iopic_input.nic_tx[channel]; 543 else if( (func == DEV_FUNC_NIC) && (is_rx != 0) ) 544 index = &iopic_input.nic_rx[channel]; 545 else if( func == DEV_FUNC_IOB ) 546 index = &iopic_input.iob; 547 else 548 assert( false , __FUNCTION__ , "illegal source device for IOPIC input" ); 549 550 // set entry in local structure 551 *index = id; 578 func = FUNC_FROM_TYPE( type ); 579 580 // get pointer on relevant field in iopic_input 581 if( valid ) 582 { 583 if ( func == DEV_FUNC_IOC ) ptr = &iopic_input.ioc[channel]; 584 else if((func == DEV_FUNC_TXT) && (is_rx == 0)) ptr = &iopic_input.txt_tx[channel]; 585 else if((func == DEV_FUNC_TXT) && (is_rx != 0)) ptr = &iopic_input.txt_rx[channel]; 586 else if((func == DEV_FUNC_NIC) && (is_rx == 0)) ptr = &iopic_input.nic_tx[channel]; 587 else if((func == DEV_FUNC_NIC) && (is_rx != 0)) ptr = &iopic_input.nic_rx[channel]; 588 else if( func == DEV_FUNC_IOB ) ptr = &iopic_input.iob; 589 else panic( "illegal source device for IOPIC input" ); 590 591 // set one entry in all "iopic_input" structures 592 for( x = 0 ; x < info->x_size ; x++ ) 593 { 594 for( y = 0 ; y < info->y_size ; y++ ) 595 { 596 cxy_t cxy = (x<<info->y_width) + y; 597 hal_remote_swd( XPTR( cxy , ptr ) , id ); 598 } 599 } 552 600 } 553 601 } 554 602 555 #if( CONFIG_KINIT_DEBUG > 1 ) 556 printk("\n[DMSG] %s created PIC chdev in cluster %x at cycle %d\n", 557 __FUNCTION__ , local_cxy , (uint32_t)hal_time_stamp() ); 603 #if( CONFIG_KINIT_DEBUG & 0x1 ) 604 if( hal_time_stamp() > CONFIG_KINIT_DEBUG ) 605 { 606 printk("\n[DBG] %s created PIC chdev in cluster %x at cycle %d\n", 607 __FUNCTION__ , local_cxy , (uint32_t)hal_time_stamp() ); 608 dev_pic_inputs_display(); 609 } 558 610 #endif 559 611 … … 715 767 hal_set_current_thread( thread ); 716 768 717 // each core initializes the idle thread "locks_root" and "xlocks_root" fields 769 // each core register core descriptor pointer in idle thread descriptor 770 thread->core = &LOCAL_CLUSTER->core_tbl[core_lid]; 771 772 // each core initializes locks_root" and "xlocks_root" in idle thread descriptor 718 773 list_root_init( &thread->locks_root ); 719 774 xlist_root_init( XPTR( local_cxy , &thread->xlocks_root ) ); … … 728 783 729 784 if( (core_lid == 0) && (local_cxy == 0) ) 730 printk("\n[KINIT] %s : exit barrier 0 : TXT0 initialized / cycle %d\n",785 kinit_dmsg("\n[DBG] %s : exit barrier 0 : TXT0 initialized / cycle %d\n", 731 786 __FUNCTION__, hal_time_stamp() ); 732 787 733 788 ///////////////////////////////////////////////////////////////////////////// 734 // STEP 1 : all cores check itscore identifier.789 // STEP 1 : all cores check core identifier. 735 790 // CP0 initializes the local cluster manager. 736 791 // This includes the memory allocators. … … 762 817 763 818 if( (core_lid == 0) && (local_cxy == 0) ) 764 printk("\n[KINIT] %s : exit barrier 1 : clusters initialised / cycle %d\n",819 kinit_dmsg("\n[DBG] %s : exit barrier 1 : clusters initialised / cycle %d\n", 765 820 __FUNCTION__, hal_time_stamp() ); 766 821 767 822 ///////////////////////////////////////////////////////////////////////////////// 768 // STEP 2 : all CP0s initializethe process_zero descriptor.823 // STEP 2 : CP0 initializes the process_zero descriptor. 769 824 // CP0 in cluster 0 initializes the IOPIC device. 770 825 ///////////////////////////////////////////////////////////////////////////////// … … 787 842 788 843 if( (core_lid == 0) && (local_cxy == 0) ) 789 printk("\n[KINIT] %s : exit barrier 2 : PIC initialised / cycle %d\n",844 kinit_dmsg("\n[DBG] %s : exit barrier 2 : PIC initialised / cycle %d\n", 790 845 __FUNCTION__, hal_time_stamp() ); 791 846 792 847 //////////////////////////////////////////////////////////////////////////////// 793 // STEP 3 : all CP0s initializethe distibuted LAPIC descriptor.794 // all CP0s initializethe internal chdev descriptors795 // all CP0sinitialize the local external chdev descriptors848 // STEP 3 : CP0 initializes the distibuted LAPIC descriptor. 849 // CP0 initializes the internal chdev descriptors 850 // CP0 initialize the local external chdev descriptors 796 851 //////////////////////////////////////////////////////////////////////////////// 797 852 … … 818 873 819 874 if( (core_lid == 0) && (local_cxy == 0) ) 820 printk("\n[KINIT] %s : exit barrier 3 : all chdev initialised / cycle %d\n",875 kinit_dmsg("\n[DBG] %s : exit barrier 3 : all chdev initialised / cycle %d\n", 821 876 __FUNCTION__, hal_time_stamp()); 822 877 823 878 ///////////////////////////////////////////////////////////////////////////////// 824 879 // STEP 4 : All cores enable IPI (Inter Procesor Interrupt), 825 // All cores initialise specific core registers826 880 // Alh cores initialize IDLE thread. 827 881 // Only CP0 in cluster 0 creates the VFS root inode. … … 837 891 hal_enable_irq( &status ); 838 892 839 // All cores initialize specific core registers840 hal_core_init( info );841 842 893 // all cores initialize the idle thread descriptor 843 894 error = thread_kernel_init( thread, … … 857 908 858 909 #if CONFIG_KINIT_DEBUG 859 sched_display( );910 sched_display( core_lid ); 860 911 #endif 861 912 … … 928 979 929 980 if( (core_lid == 0) && (local_cxy == 0) ) 930 printk("\n[KINIT] %s : exit barrier 4 : VFS_root = %l in cluster 0 / cycle %d\n",981 kinit_dmsg("\n[DBG] %s : exit barrier 4 : VFS_root = %l in cluster 0 / cycle %d\n", 931 982 __FUNCTION__, vfs_root_inode_xp , hal_time_stamp()); 932 983 … … 987 1038 988 1039 if( (core_lid == 0) && (local_cxy == 0) ) 989 printk("\n[KINIT] %s : exit barrier 5 : VFS_root = %l in cluster IO / cycle %d\n",1040 kinit_dmsg("\n[DBG] %s : exit barrier 5 : VFS_root = %l in cluster IO / cycle %d\n", 990 1041 __FUNCTION__, vfs_root_inode_xp , hal_time_stamp() ); 991 1042 … … 1020 1071 1021 1072 if( (core_lid == 0) && (local_cxy == 0) ) 1022 printk("\n[KINIT] %s : exit barrier 6 : dev_root = %l in cluster IO / cycle %d\n",1073 kinit_dmsg("\n[DBG] %s : exit barrier 6 : dev_root = %l in cluster IO / cycle %d\n", 1023 1074 __FUNCTION__, devfs_dev_inode_xp , hal_time_stamp() ); 1024 1075 … … 1057 1108 1058 1109 if( (core_lid == 0) && (local_cxy == 0) ) 1059 printk("\n[KINIT] %s : exit barrier 7 : dev_root = %l in cluster 0 / cycle %d\n",1110 kinit_dmsg("\n[DBG] %s : exit barrier 7 : dev_root = %l in cluster 0 / cycle %d\n", 1060 1111 __FUNCTION__, devfs_dev_inode_xp , hal_time_stamp() ); 1061 1112 … … 1075 1126 ///////////////////////////////////////////////////////////////////////////////// 1076 1127 1128 #if CONFIG_KINIT_DEBUG 1129 sched_display( core_lid ); 1130 #endif 1131 1077 1132 if( (core_lid == 0) && (local_cxy == 0) ) 1078 printk("\n[KINIT] %s : exit barrier 8 : process init created / cycle %d\n",1133 kinit_dmsg("\n[DBG] %s : exit barrier 8 : process init created / cycle %d\n", 1079 1134 __FUNCTION__ , hal_time_stamp() ); 1080 1135 … … 1118 1173 sizeof( core_t ), 1119 1174 sizeof( scheduler_t ), 1120 sizeof( r pc_fifo_t),1175 sizeof( remote_fifo_t ), 1121 1176 sizeof( page_t ), 1122 1177 sizeof( mapper_t ), … … 1139 1194 dev_pic_enable_timer( CONFIG_SCHED_TICK_MS_PERIOD ); 1140 1195 1141 // each core jump to idle thread1196 // each core jump to thread_idle_func 1142 1197 thread_idle_func(); 1143 1198 } -
trunk/kernel/kern/printk.c
r406 r407 190 190 goto xprintf_text; 191 191 } 192 } // end xprintf() 193 194 /////////////////////////////////////////////////////////////////////////////////// 195 // This static function is called by kernel_printf() to display a string on the 196 // TXT channel defined by the <channel> argument. 197 // The access mode is defined by the <busy> argument: 198 // - if <busy> is true, it uses the dev_txt_sync_write() function, that takes the 199 // TXT lock, and call directly the relevant TXT driver, without descheduling. 200 // - if <busy is false, it uses the dev_txt_write() function, that register the 201 // write buffer in the relevant TXT chdev queue, and uses a descheduling policy. 202 /////////////////////////////////////////////////////////////////////////////////// 203 // @ channel : TXT channel. 204 // @ busy : TXT device acces mode (busy waiting if non zero). 205 // @ buf : buffer containing the characters. 206 // @ nc : number of characters. 207 // return 0 if success / return -1 if TTY0 busy after 10000 retries. 208 /////////////////////////////////////////////////////////////////////////////////// 209 static error_t txt_write( uint32_t channel, 210 uint32_t busy, 211 char * buffer, 212 uint32_t count ) 213 { 214 if( busy ) return dev_txt_sync_write( channel , buffer , count ); 215 else return dev_txt_write( channel , buffer , count ); 216 } 192 } // end snprintf() 217 193 218 194 ////////////////////////////////////////////////////////////////////////////////////// 219 // This static function is called by printk(), assert() and nolock_printk() to build220 // a formated string.195 // This static function is called by printk(), assert() and nolock_printk() 196 // to display a formated string on TXT0, using a busy waiting policy. 221 197 ////////////////////////////////////////////////////////////////////////////////////// 222 // @ channel : channel index.223 // @ busy : TXT device access mode (busy waiting if non zero).224 198 // @ format : printf like format. 225 // @ args : formatarguments.199 // @ args : va_list of arguments. 226 200 ////////////////////////////////////////////////////////////////////////////////////// 227 static void kernel_printf( uint32_t channel, 228 uint32_t busy, 229 char * format, 201 static void kernel_printf( char * format, 230 202 va_list * args ) 231 203 { … … 239 211 if (i) 240 212 { 241 txt_write( channel, busy,format, i );213 dev_txt_sync_write( format, i ); 242 214 format += i; 243 215 } … … 276 248 { 277 249 val = -val; 278 txt_write( channel, busy,"-" , 1 );250 dev_txt_sync_write( "-" , 1 ); 279 251 } 280 252 for(i = 0; i < 10; i++) … … 302 274 { 303 275 uint32_t val = va_arg( *args , uint32_t ); 304 txt_write( channel, busy,"0x" , 2 );276 dev_txt_sync_write( "0x" , 2 ); 305 277 for(i = 0; i < 8; i++) 306 278 { … … 315 287 { 316 288 uint32_t val = va_arg( *args , uint32_t ); 317 txt_write( channel, busy,"0x" , 2 );289 dev_txt_sync_write( "0x" , 2 ); 318 290 for(i = 0; i < 8; i++) 319 291 { … … 328 300 { 329 301 unsigned long long val = va_arg( *args , unsigned long long ); 330 txt_write( channel, busy,"0x" , 2 );302 dev_txt_sync_write( "0x" , 2 ); 331 303 for(i = 0; i < 16; i++) 332 304 { … … 341 313 { 342 314 unsigned long long val = va_arg( *args , unsigned long long ); 343 txt_write( channel, busy,"0x" , 2 );315 dev_txt_sync_write( "0x" , 2 ); 344 316 for(i = 0; i < 16; i++) 345 317 { … … 363 335 default: 364 336 { 365 txt_write( channel , busy, 366 "\n[PANIC] in kernel_printf() : illegal format\n", 45 ); 367 } 368 } 369 370 if( pbuf != NULL ) txt_write( channel, busy, pbuf, len ); 337 dev_txt_sync_write( "\n[PANIC] in kernel_printf() : illegal format\n", 45 ); 338 } 339 } 340 341 if( pbuf != NULL ) dev_txt_sync_write( pbuf, len ); 371 342 372 343 goto printf_text; … … 382 353 383 354 // get pointers on TXT0 chdev 384 xptr_t txt0_xp = chdev_dir.txt [0];355 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 385 356 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 386 357 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); … … 394 365 // call kernel_printf on TXT0, in busy waiting mode 395 366 va_start( args , format ); 396 kernel_printf( 0 , 1 ,format , &args );367 kernel_printf( format , &args ); 397 368 va_end( args ); 398 369 … … 408 379 // call kernel_printf on TXT0, in busy waiting mode 409 380 va_start( args , format ); 410 kernel_printf( 0 , 1 ,format , &args );381 kernel_printf( format , &args ); 411 382 va_end( args ); 412 383 } … … 419 390 420 391 // get pointers on TXT0 chdev 421 xptr_t txt0_xp = chdev_dir.txt [0];392 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 422 393 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 423 394 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); … … 431 402 // call kernel_printf on TXT0, in busy waiting mode 432 403 va_start( args , format ); 433 kernel_printf( 0 , 1 ,format , &args );404 kernel_printf( format , &args ); 434 405 va_end( args ); 435 406 … … 456 427 { 457 428 // get pointers on TXT0 chdev 458 xptr_t txt0_xp = chdev_dir.txt [0];429 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 459 430 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 460 431 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); … … 471 442 // call kernel_printf on TXT0, in busy waiting to print format 472 443 va_start( args , format ); 473 kernel_printf( 0 , 1 ,format , &args );444 kernel_printf( format , &args ); 474 445 va_end( args ); 475 446 -
trunk/kernel/kern/printk.h
r406 r407 102 102 char * format , ... ); 103 103 104 #define panic(fmt, ...) _panic(" [PANIC] %s(): " fmt "\n", __func__, ##__VA_ARGS__)104 #define panic(fmt, ...) _panic("\n[PANIC] %s(): " fmt "\n", __func__, ##__VA_ARGS__) 105 105 106 106 /////////////////////////////////////////////////////////////////////////////////// … … 108 108 /////////////////////////////////////////////////////////////////////////////////// 109 109 110 #if CONFIG_CHDEV_DEBUG 111 #define chdev_dmsg(...) if(hal_time_stamp() > CONFIG_CHDEV_DEBUG) printk(__VA_ARGS__) 112 #else 113 #define chdev_dmsg(...) 114 #endif 115 110 116 #if CONFIG_CLUSTER_DEBUG 111 117 #define cluster_dmsg(...) if(hal_time_stamp() > CONFIG_CLUSTER_DEBUG) printk(__VA_ARGS__) … … 186 192 #endif 187 193 194 #if CONFIG_GRPC_DEBUG 195 #define grpc_dmsg(...) if(hal_time_stamp() > CONFIG_GRPC_DEBUG) printk(__VA_ARGS__) 196 #else 197 #define grpc_dmsg(...) 198 #endif 199 188 200 #if CONFIG_IDLE_DEBUG 189 201 #define idle_dmsg(...) if(hal_time_stamp() > CONFIG_IDLE_DEBUG) printk(__VA_ARGS__) … … 234 246 #endif 235 247 248 #if CONFIG_MMAP_DEBUG 249 #define mmap_dmsg(...) if(hal_time_stamp() > CONFIG_MMAP_DEBUG) printk(__VA_ARGS__) 250 #else 251 #define mmap_dmsg(...) 252 #endif 253 236 254 #if CONFIG_MMC_DEBUG 237 255 #define mmc_dmsg(...) if(hal_time_stamp() > CONFIG_MMC_DEBUG) printk(__VA_ARGS__) … … 264 282 #endif 265 283 284 #if CONFIG_READ_DEBUG 285 #define read_dmsg(...) if(hal_time_stamp() > CONFIG_READ_DEBUG) printk(__VA_ARGS__) 286 #else 287 #define read_dmsg(...) 288 #endif 289 266 290 #if CONFIG_RPC_DEBUG 267 291 #define rpc_dmsg(...) if(hal_time_stamp() > CONFIG_RPC_DEBUG) printk(__VA_ARGS__) … … 310 334 #else 311 335 #define vmm_dmsg(...) 336 #endif 337 338 #if CONFIG_WRITE_DEBUG 339 #define write_dmsg(...) if(hal_time_stamp() > CONFIG_WRITE_DEBUG) printk(__VA_ARGS__) 340 #else 341 #define write_dmsg(...) 312 342 #endif 313 343 -
trunk/kernel/kern/process.c
r406 r407 39 39 #include <thread.h> 40 40 #include <list.h> 41 #include <string.h> 41 42 #include <scheduler.h> 42 43 #include <remote_spinlock.h> … … 90 91 pid_t parent_pid; 91 92 92 process_dmsg("\n[DMSG] %s : core[%x,%d] enters for process %x\n", 93 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid ); 93 error_t error1; 94 error_t error2; 95 error_t error3; 96 xptr_t stdin_xp; 97 xptr_t stdout_xp; 98 xptr_t stderr_xp; 99 uint32_t stdin_id; 100 uint32_t stdout_id; 101 uint32_t stderr_id; 102 103 process_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x\n", 104 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid ); 94 105 95 106 // get parent process cluster, local pointer, and pid 96 // for all processes other than process_zero97 if( process == &process_zero ) 107 // for all processes other than kernel process 108 if( process == &process_zero ) // kernel process 98 109 { 99 110 assert( (pid == 0) , __FUNCTION__ , "process_zero must have PID = 0\n"); … … 101 112 parent_cxy = 0; 102 113 parent_ptr = NULL; 103 parent_pid = 0; // process_zero is its own parent... 104 } 105 else 106 { 107 assert( (parent_xp != XPTR_NULL) , __FUNCTION__ , "parent_xp cannot be NULL\n"); 108 114 parent_pid = 0; 115 } 116 else // user process 117 { 109 118 parent_cxy = GET_CXY( parent_xp ); 110 119 parent_ptr = (process_t *)GET_PTR( parent_xp ); … … 112 121 } 113 122 114 // initialize PID and PPID 115 process->pid = pid; 116 process->ppid = parent_pid; 117 118 // initialize reference process vmm (not for kernel process) 119 if( pid ) vmm_init( process ); 120 121 // reset reference process file descriptors array 122 process_fd_init( process ); 123 124 // reset reference process files structures and cwd_lock 125 process->vfs_root_xp = XPTR_NULL; 126 process->vfs_bin_xp = XPTR_NULL; 127 process->vfs_cwd_xp = XPTR_NULL; 128 remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ) ); 129 130 // reset children list root 131 xlist_root_init( XPTR( local_cxy , &process->children_root ) ); 132 process->children_nr = 0; 133 134 // reset semaphore / mutex / barrier / condvar list roots 135 xlist_root_init( XPTR( local_cxy , &process->sem_root ) ); 136 xlist_root_init( XPTR( local_cxy , &process->mutex_root ) ); 137 xlist_root_init( XPTR( local_cxy , &process->barrier_root ) ); 138 xlist_root_init( XPTR( local_cxy , &process->condvar_root ) ); 139 remote_spinlock_init( XPTR( local_cxy , &process->sync_lock ) ); 140 141 // register new process in the parent children list (not for kernel process) 123 // initialize PID, PPID, and REF 124 process->pid = pid; 125 process->ppid = parent_pid; 126 process->ref_xp = XPTR( local_cxy , process ); 127 128 // initialize vmm, fd array and others structures for user processes. 129 // These structures are not used by the kernel process. 142 130 if( pid ) 143 131 { 132 // initialize vmm (not for kernel) 133 vmm_init( process ); 134 135 process_dmsg("\n[DBG] %s : core[%x,%d] / vmm initialised for process %x\n", 136 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid ); 137 138 // initialize fd_array (not for kernel) 139 process_fd_init( process ); 140 141 // create stdin / stdout / stderr pseudo-files (not for kernel) 142 if( parent_pid == 0 ) // process_init 143 { 144 error1 = vfs_open( process, 145 CONFIG_INIT_STDIN, 146 O_RDONLY, 147 0, // FIXME chmod 148 &stdin_xp, 149 &stdin_id ); 150 151 error2 = vfs_open( process, 152 CONFIG_INIT_STDOUT, 153 O_WRONLY, 154 0, // FIXME chmod 155 &stdout_xp, 156 &stdout_id ); 157 158 error3 = vfs_open( process, 159 CONFIG_INIT_STDERR, 160 O_WRONLY, 161 0, // FIXME chmod 162 &stderr_xp, 163 &stderr_id ); 164 } 165 else // user process 166 { 167 error1 = vfs_open( process, 168 CONFIG_USER_STDIN, 169 O_RDONLY, 170 0, // FIXME chmod 171 &stdin_xp, 172 &stdin_id ); 173 174 error2 = vfs_open( process, 175 CONFIG_USER_STDOUT, 176 O_WRONLY, 177 0, // FIXME chmod 178 &stdout_xp, 179 &stdout_id ); 180 181 error3 = vfs_open( process, 182 CONFIG_USER_STDERR, 183 O_WRONLY, 184 0, // FIXME chmod 185 &stderr_xp, 186 &stderr_id ); 187 } 188 189 assert( ((error1 == 0) && (error2 == 0) && (error3 == 0)) , __FUNCTION__ , 190 "cannot open stdin/stdout/stderr pseudo files\n"); 191 192 assert( ((stdin_id == 0) && (stdout_id == 1) && (stderr_id == 2)) , __FUNCTION__ , 193 "bad indexes : stdin %d / stdout %d / stderr %d \n", stdin_id , stdout_id , stderr_id ); 194 195 process_dmsg("\n[DBG] %s : core[%x,%d] / fd array initialised for process %x\n", 196 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid ); 197 198 199 // reset reference process files structures and cwd_lock (not for kernel) 200 process->vfs_root_xp = XPTR_NULL; 201 process->vfs_bin_xp = XPTR_NULL; 202 process->vfs_cwd_xp = XPTR_NULL; 203 remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ) ); 204 205 // reset children list root (not for kernel) 206 xlist_root_init( XPTR( local_cxy , &process->children_root ) ); 207 process->children_nr = 0; 208 209 // reset semaphore / mutex / barrier / condvar list roots (nor for kernel) 210 xlist_root_init( XPTR( local_cxy , &process->sem_root ) ); 211 xlist_root_init( XPTR( local_cxy , &process->mutex_root ) ); 212 xlist_root_init( XPTR( local_cxy , &process->barrier_root ) ); 213 xlist_root_init( XPTR( local_cxy , &process->condvar_root ) ); 214 remote_spinlock_init( XPTR( local_cxy , &process->sync_lock ) ); 215 216 // register new process in the parent children list (nor for kernel) 144 217 xptr_t entry = XPTR( local_cxy , &process->brothers_list ); 145 218 xptr_t root = XPTR( parent_cxy , &parent_ptr->children_root ); … … 156 229 spinlock_init( &process->th_lock ); 157 230 158 // set ref_xp field159 process->ref_xp = XPTR( local_cxy , process );160 161 231 // register new process descriptor in local cluster manager local_list 162 232 cluster_process_local_link( process ); … … 169 239 hal_fence(); 170 240 171 process_dmsg("\n[DMSG] %s : exit for process %x in cluster%x\n",172 __FUNCTION__, pid );241 process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x\n", 242 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pid ); 173 243 174 244 } // process_reference init() … … 181 251 cxy_t ref_cxy = GET_CXY( reference_process_xp ); 182 252 process_t * ref_ptr = (process_t *)GET_PTR( reference_process_xp ); 253 254 // set the pid, ppid, ref_xp fields in local process 255 local_process->pid = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->pid ) ); 256 local_process->ppid = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->ppid ) ); 257 local_process->ref_xp = reference_process_xp; 258 259 process_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x in cluster %x\n", 260 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , local_process->pid ); 183 261 184 262 // reset local process vmm … … 192 270 local_process->vfs_bin_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_bin_xp ) ); 193 271 local_process->vfs_cwd_xp = XPTR_NULL; 194 195 // set the pid, ppid, ref_xp fields196 local_process->pid = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->pid ) );197 local_process->ppid = hal_remote_lw( XPTR( ref_cxy , &ref_ptr->ppid ) );198 local_process->ref_xp = reference_process_xp;199 200 process_dmsg("\n[DMSG] %s : enter for process %x in cluster %x\n",201 __FUNCTION__ , local_process->pid );202 272 203 273 // reset children list root (not used in a process descriptor copy) … … 233 303 hal_fence(); 234 304 235 process_dmsg("\n[DMSG] %s :exit for process %x in cluster %x\n",236 __FUNCTION__, local_process->pid );305 process_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x in cluster %x\n", 306 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , local_process->pid ); 237 307 238 308 return 0; … … 288 358 vmm_destroy( process ); 289 359 290 process_dmsg("\n[D MSG] %s for pid %d / page_faults = %d\n",360 process_dmsg("\n[DBG] %s for pid %d / page_faults = %d\n", 291 361 __FUNCTION__ , process->pid, process->vmm.pgfault_nr ); 292 } 362 363 } // end process_destroy() 293 364 294 365 //////////////////////////////////////// … … 298 369 uint32_t ltid; // index in process th_tbl 299 370 uint32_t count; // thread counter 371 372 printk("\n@@@ %s enter\n", __FUNCTION__ ); 300 373 301 374 // get lock protecting th_tbl[] … … 317 390 } 318 391 319 volatile uint32_t ko;392 printk("\n@@@ %s : %d signal(s) sent\n", __FUNCTION__, count ); 320 393 321 394 // second loop on threads to wait acknowledge from scheduler, … … 329 402 if( thread != NULL ) 330 403 { 331 // wait scheduler acknowledge 332 do { ko = (thread->signals & THREAD_SIG_KILL); } while( ko ); 333 334 // unlink thread from brothers list if required 335 if( (thread->flags & THREAD_FLAG_DETACHED) == 0 ) 336 xlist_unlink( XPTR( local_cxy , &thread->brothers_list ) ); 404 405 printk("\n@@@ %s start polling at cycle %d\n", __FUNCTION__ , hal_time_stamp() ); 406 407 // poll the THREAD_SIG_KILL bit until reset 408 while( thread->signals & THREAD_SIG_KILL ) asm volatile( "nop" ); 409 410 printk("\n@@@ %s exit polling\n", __FUNCTION__ ); 411 412 // detach target thread from parent if attached 413 if( (thread->flags & THREAD_FLAG_DETACHED) != 0 ) 414 thread_child_parent_unlink( thread->parent , XPTR( local_cxy , thread ) ); 337 415 338 416 // unlink thread from process … … 346 424 } 347 425 426 printk("\n@@@ %s : %d ack(s) received\n", __FUNCTION__, count ); 427 348 428 // release lock protecting th_tbl[] 349 429 spinlock_unlock( &process->th_lock ); … … 351 431 // release memory allocated for process descriptor 352 432 process_destroy( process ); 353 } 433 434 printk("\n[@@@] %s : core[%x,%d] exit\n", 435 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid ); 436 437 } // end process_kill() 354 438 355 439 /////////////////////////////////////////////// … … 440 524 441 525 ///////////////////////////////////////////////// 442 error_t process_fd_register( xptr_t file_xp, 443 uint32_t * file_id ) 526 error_t process_fd_register( process_t * process, 527 xptr_t file_xp, 528 uint32_t * fdid ) 444 529 { 445 530 bool_t found; … … 447 532 xptr_t xp; 448 533 449 // get extended pointer on reference process450 xptr_t ref_xp = CURRENT_THREAD->process->ref_xp;451 452 534 // get reference process cluster and local pointer 535 xptr_t ref_xp = process->ref_xp; 453 536 process_t * ref_ptr = (process_t *)GET_PTR( ref_xp ); 454 537 cxy_t ref_cxy = GET_CXY( ref_xp ); … … 467 550 hal_remote_swd( XPTR( ref_cxy , &ref_ptr->fd_array.array[id] ) , file_xp ); 468 551 hal_remote_atomic_add( XPTR( ref_cxy , &ref_ptr->fd_array.current ) , 1 ); 469 *f ile_id = id;552 *fdid = id; 470 553 break; 471 554 } … … 481 564 //////////////////////////////////////////////// 482 565 xptr_t process_fd_get_xptr( process_t * process, 483 uint32_t f ile_id )566 uint32_t fdid ) 484 567 { 485 568 xptr_t file_xp; 486 569 487 570 // access local copy of process descriptor 488 file_xp = process->fd_array.array[f ile_id];571 file_xp = process->fd_array.array[fdid]; 489 572 490 573 if( file_xp == XPTR_NULL ) … … 496 579 497 580 // access reference process descriptor 498 file_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->fd_array.array[f ile_id] ) );581 file_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->fd_array.array[fdid] ) ); 499 582 500 583 // update local fd_array if found 501 584 if( file_xp != XPTR_NULL ) 502 585 { 503 process->fd_array.array[f ile_id] = file_xp;586 process->fd_array.array[fdid] = file_xp; 504 587 } 505 588 } 506 589 507 590 return file_xp; 508 } 591 592 } // end process_fd_get_xptr() 509 593 510 594 /////////////////////////////////////////// … … 543 627 // release lock on source process fd_array 544 628 remote_spinlock_unlock( XPTR( src_cxy , &src_ptr->lock ) ); 545 } 629 630 } // end process_fd_remote_copy() 546 631 547 632 //////////////////////////////////////////////////////////////////////////////////// … … 561 646 assert( (thread != NULL) , __FUNCTION__ , "thread argument is NULL" ); 562 647 563 // search a free slot in th_tbl[] 648 // search a free slot in th_tbl[] 649 // 0 is not a valid ltid value 564 650 found = false; 565 for( ltid = 0; ltid < CONFIG_THREAD_MAX_PER_CLUSTER ; ltid++ )651 for( ltid = 1 ; ltid < CONFIG_THREAD_MAX_PER_CLUSTER ; ltid++ ) 566 652 { 567 653 if( process->th_tbl[ltid] == NULL ) … … 606 692 { 607 693 char * path; // pathname to .elf file 694 bool_t keep_pid; // new process keep parent PID if true 608 695 process_t * process; // local pointer on new process 609 696 pid_t pid; // new process pid 610 697 xptr_t parent_xp; // extended pointer on parent process 611 cxy_t parent_cxy; 612 process_t * parent_ptr; 613 uint32_t parent_pid; 698 cxy_t parent_cxy; // parent process local cluster 699 process_t * parent_ptr; // local pointer on parent process 700 uint32_t parent_pid; // parent process identifier 614 701 thread_t * thread; // pointer on new thread 615 702 pthread_attr_t attr; // main thread attributes … … 618 705 error_t error; 619 706 620 // get parent and .elf pathnamefrom exec_info707 // get .elf pathname, parent_xp, and keep_pid flag from exec_info 621 708 path = exec_info->path; 622 709 parent_xp = exec_info->parent_xp; 710 keep_pid = exec_info->keep_pid; 711 712 process_dmsg("\n[DBG] %s : core[%x,%d] enters for path = %s\n", 713 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path ); 623 714 624 715 // get parent process cluster and local pointer … … 627 718 parent_pid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) ); 628 719 629 exec_dmsg("\n[DMSG] %s : thread %x on core[%x,%d] enters for path = %s\n", 630 __FUNCTION__, CURRENT_THREAD->trdid, local_cxy, CURRENT_THREAD->core->lid , path ); 631 632 // create new process descriptor 633 process = process_alloc(); 634 635 if( process == NULL ) 636 { 637 printk("\n[ERROR] in %s : no memory / cluster = %x / ppid = %x / path = %s\n", 638 __FUNCTION__ , local_cxy , parent_pid , path ); 639 return ENOMEM; 640 } 641 642 // get a pid from the local cluster 643 error = cluster_pid_alloc( XPTR( local_cxy , process ) , &pid ); 644 645 if( error ) 646 { 647 printk("\n[ERROR] in %s : cannot get PID / cluster = %x / ppid = %x / path = %s\n", 648 __FUNCTION__ , local_cxy , parent_pid , path ); 649 process_free( process ); 650 return ENOMEM; 651 } 720 // allocates memory for process descriptor 721 process = process_alloc(); 722 if( process == NULL ) return -1; 723 724 // get PID 725 if( keep_pid ) // keep parent PID 726 { 727 pid = parent_pid; 728 } 729 else // get new PID from local cluster 730 { 731 error = cluster_pid_alloc( XPTR( local_cxy , process ) , &pid ); 732 if( error ) return -1; 733 } 734 735 process_dmsg("\n[DBG] %s : core[%x,%d] created process %x for path = %s\n", 736 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid, path ); 652 737 653 738 // initialize the process descriptor as the reference 654 739 process_reference_init( process , pid , parent_xp ); 655 740 656 exec_dmsg("\n[DMSG] %s : thread %x on core[%x,%d] created process %x / path = %s\n",657 __FUNCTION__, CURRENT_THREAD->trdid, local_cxy, CURRENT_THREAD->core->lid, pid, path );741 process_dmsg("\n[DBG] %s : core[%x,%d] initialized process %x / path = %s\n", 742 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid, path ); 658 743 659 744 // initialize vfs_root and vfs_cwd from parent process … … 670 755 XPTR( parent_cxy , &parent_ptr->fd_array) ); 671 756 672 exec_dmsg("\n[DMSG] %s : fd_array copied from process %x to process %x\n", 673 __FUNCTION__, parent_pid , pid ); 674 675 // initialize signal manager TODO ??? [AG] 676 // signal_manager_init( process ); 757 process_dmsg("\n[DBG] %s : core[%x,%d] copied fd_array for process %x\n", 758 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid ); 677 759 678 760 // register "code" and "data" vsegs as well as the process entry-point in VMM, … … 682 764 if( error ) 683 765 { 684 printk("\n[ERROR] in %s : failed to access elf file for process %x / path = %s\n",766 printk("\n[ERROR] in %s : failed to access .elf file for process %x / path = %s\n", 685 767 __FUNCTION__, pid , path ); 686 768 process_destroy( process ); … … 688 770 } 689 771 690 exec_dmsg("\n[DMSG] %s : code and data vsegs registeredfor process %x / path = %s\n",691 __FUNCTION__ , pid, path );772 process_dmsg("\n[DBG] %s : core[%x,%d] registered code/data vsegs for process %x / path = %s\n", 773 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid, path ); 692 774 693 775 // select a core in cluster … … 709 791 { 710 792 printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n", 711 __FUNCTION__, pid );793 __FUNCTION__, pid , path ); 712 794 process_destroy( process ); 713 795 return error; 714 796 } 715 797 716 exec_dmsg("\n[DMSG] %s : thread created for process %x on core %d in cluster %x\n", 717 __FUNCTION__ , pid , core->lid , local_cxy ); 718 719 #if CONFIG_EXEC_DEBUG 720 if( hal_time_stamp() > CONFIG_EXEC_DEBUG ) 721 { 722 grdxt_print( &process->vmm.grdxt , GRDXT_TYPE_VSEG , process->pid ); 723 hal_gpt_print( &process->vmm.gpt , process->pid ); 724 } 725 #endif 798 process_dmsg("\n[DBG] %s : core[%x,%d] created thread %x for process %x / path = %s\n", 799 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, thread->trdid, pid, path ); 726 800 727 801 // update children list in parent process … … 733 807 thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL ); 734 808 735 exec_dmsg("\n[DMSG] %s : exit for process %x\n",736 __FUNCTION__, process->pid);809 process_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s\n", 810 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path ); 737 811 738 812 return 0; 739 813 740 } // end proces _make_exec()814 } // end process_make_exec() 741 815 742 816 ////////////////////////// … … 744 818 { 745 819 exec_info_t exec_info; // structure to be passed to process_make_exec() 746 747 error_t error1; 748 error_t error2; 749 error_t error3; 750 xptr_t stdin_xp; 751 xptr_t stdout_xp; 752 xptr_t stderr_xp; 753 uint32_t stdin_id; 754 uint32_t stdout_id; 755 uint32_t stderr_id; 756 757 process_dmsg("\n[DMSG] %s : enters in cluster %x\n", __FUNCTION__ , local_cxy ); 758 759 // open stdin / stdout / stderr pseudo-files 760 error1 = vfs_open( XPTR_NULL, CONFIG_DEV_STDIN , O_RDONLY, 0, &stdin_xp , &stdin_id ); 761 error2 = vfs_open( XPTR_NULL, CONFIG_DEV_STDOUT, O_WRONLY, 0, &stdout_xp, &stdout_id ); 762 error3 = vfs_open( XPTR_NULL, CONFIG_DEV_STDERR, O_WRONLY, 0, &stderr_xp, &stderr_id ); 763 764 assert( ((error1 == 0) && (error2 == 0) && (error3 == 0)) , __FUNCTION__ , 765 "cannot open stdin/stdout/stderr pseudo files\n"); 766 767 assert( ((stdin_id == 0) && (stdout_id == 1) && (stderr_id == 2)) , __FUNCTION__ , 768 "bad indexes for stdin/stdout/stderr\n"); 820 xptr_t parent_xp; // extended pointer on parent process. 821 error_t error; 822 823 process_dmsg("\n[DBG] %s : enters in cluster %x\n", 824 __FUNCTION__ , local_cxy ); 825 826 // parent process is local kernel process 827 parent_xp = XPTR( local_cxy , &process_zero ); 769 828 770 829 // initialize the exec_info structure 771 exec_info.parent_xp = XPTR( local_cxy , &process_zero ); 830 exec_info.keep_pid = false; 831 exec_info.parent_xp = parent_xp; 772 832 strcpy( exec_info.path , CONFIG_PROCESS_INIT_PATH ); 773 833 exec_info.args_nr = 0; 774 834 exec_info.envs_nr = 0; 775 835 776 // create process_init and thread_init 777 error1 = process_make_exec( &exec_info ); 778 779 assert( (error1 == 0) , __FUNCTION__ , "cannot create process_init\n"); 780 781 process_dmsg("\n[DMSG] %s : exit in cluster %x\n", __FUNCTION__ , local_cxy ); 836 // initialize process_init and create thread_init 837 error = process_make_exec( &exec_info ); 838 839 if( error ) panic("cannot initialize process_init in cluster %x", local_cxy ); 840 841 process_dmsg("\n[DBG] %s : exit in cluster %x\n", 842 __FUNCTION__ , local_cxy ); 782 843 783 844 hal_fence(); -
trunk/kernel/kern/process.h
r204 r407 143 143 { 144 144 xptr_t parent_xp; /*! extended pointer on parent process descriptor */ 145 bool_t keep_pid; /*! keep parent PID if true / new PID if false */ 145 146 146 147 char path[CONFIG_VFS_MAX_PATH_LENGTH]; /*! .elf file path */ … … 175 176 /********************************************************************************************* 176 177 * This function allocates memory and initializes the "process_init" descriptor and the 177 * associated "thread_init" descriptor . It should be called once at the end of the kernel178 * initialisation procedure, by the kernel "process_zero".178 * associated "thread_init" descriptor in the local cluster. It is called once at the end 179 * of the kernel initialisation procedure, by the local kernel process. 179 180 * The "process_init" is the first user process, and all other user processes will be forked 180 181 * from this process. The code executed by "process_init" is stored in a .elf file, whose 181 * pathname is defined by the CONFIG_PROCESS_INIT_PATH argument. It uses fork/exec syscalls 182 * to create the "shell" user process, and various other user daemon processes. 183 * Practically, it builds the exec_info structure, registers the stdin / stdout / stderr 184 * pseudo-file descriptors and the vfs_root and vfs_cwd in parent process_zero, and calls 185 * the generic process_make_exec() function, that makes the real job. 182 * pathname is defined by the CONFIG_PROCESS_INIT_PATH argument. 183 * Practically, it builds the exec_info structure, and calls the process_make_exec() 184 * function, that make the real job. 186 185 ********************************************************************************************/ 187 186 void process_init_create(); … … 253 252 * and the associated main thread, from information found in the <exec_info> structure 254 253 * (defined in the process.h file), that must be built by the caller. 254 * - If the <keep_pid> field is true, the new process inherits its PID from the parent PID. 255 * - If the <keep_pid> field is false, a new PID is allocated from the local cluster manager. 255 256 * The new process inherits from the parent process (i) the open file descriptors, (ii) the 256 257 * vfs_root and the vfs_cwd inodes. … … 268 269 269 270 270 /******************** Signal Management Operations **************************************/271 272 /*********************************************************************************************273 * This function TODO [AG]274 ********************************************************************************************/275 void process_signal_handler( process_t * process );276 277 278 271 /******************** File Management Operations ****************************************/ 279 272 … … 287 280 /********************************************************************************************* 288 281 * This function uses as many remote accesses as required, to reset an entry in fd_array[], 289 * in all clusters containing a copy. The entry is identified by the <f ile_id> argument.282 * in all clusters containing a copy. The entry is identified by the <fdid> argument. 290 283 * This function must be executed by a thread running reference cluster, that contains 291 284 * the complete list of process descriptors copies. 292 285 ********************************************************************************************* 293 286 * @ process : pointer on the local process descriptor. 294 * @ f ile_id: file descriptor index in the fd_array.287 * @ fdid : file descriptor index in the fd_array. 295 288 ********************************************************************************************/ 296 289 void process_fd_remove( process_t * process, 297 uint32_t f ile_id );290 uint32_t fdid ); 298 291 299 292 /********************************************************************************************* … … 306 299 ********************************************************************************************* 307 300 * @ process : pointer on the local process descriptor. 308 * @ f ile_id: file descriptor index in the fd_array.301 * @ fdid : file descriptor index in the fd_array. 309 302 * @ return extended pointer on file descriptor if success / return XPTR_NULL if not found. 310 303 ********************************************************************************************/ 311 304 xptr_t process_fd_get_xptr( process_t * process, 312 uint32_t f ile_id );305 uint32_t fdid ); 313 306 314 307 /********************************************************************************************* … … 328 321 ********************************************************************************************* 329 322 * @ file_xp : extended pointer on the file descriptor to be registered. 330 * @ f ile_id: [out] buffer for fd_array slot index.323 * @ fdid : [out] buffer for fd_array slot index. 331 324 * @ return 0 if success / return EMFILE if array full. 332 325 ********************************************************************************************/ 333 error_t process_fd_register( xptr_t file_xp, 334 uint32_t * file_id ); 326 error_t process_fd_register( process_t * process, 327 xptr_t file_xp, 328 uint32_t * fdid ); 335 329 336 330 /********************************************************************************************* -
trunk/kernel/kern/rpc.c
r406 r407 76 76 &rpc_mapper_move_buffer_server, // 24 77 77 &rpc_mapper_get_page_server, // 25 78 &rpc_ undefined,// 2679 &rpc_ undefined,// 2778 &rpc_vmm_create_vseg_server, // 26 79 &rpc_sched_display_server, // 27 80 80 &rpc_undefined, // 28 81 81 &rpc_undefined, // 29 … … 97 97 page_t ** page ) // out 98 98 { 99 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",99 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 100 100 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 101 101 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 115 115 116 116 // get output arguments from RPC descriptor 117 *page 118 119 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",117 *page = (page_t *)(intptr_t)rpc.args[1]; 118 119 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 120 120 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 121 121 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 125 125 void rpc_pmem_get_pages_server( xptr_t xp ) 126 126 { 127 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",127 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 128 128 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 129 129 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 142 142 hal_remote_swd( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page ); 143 143 144 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",144 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 145 145 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 146 146 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 157 157 pid_t * pid ) // out 158 158 { 159 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",159 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 160 160 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 161 161 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 178 178 *error = (error_t)rpc.args[2]; 179 179 180 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",180 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 181 181 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 182 182 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 190 190 pid_t pid; // output : process identifier 191 191 192 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",192 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 193 193 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 194 194 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 209 209 hal_remote_sw( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)pid ); 210 210 211 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",211 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 212 212 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 213 213 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 224 224 error_t * error ) // out 225 225 { 226 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",226 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 227 227 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 228 228 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 244 244 *error = (error_t)rpc.args[1]; 245 245 246 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",246 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 247 247 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 248 248 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 256 256 error_t error; // local error error status 257 257 258 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",258 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 259 259 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 260 260 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 278 278 hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error ); 279 279 280 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",280 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 281 281 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 282 282 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 291 291 void rpc_process_kill_client( process_t * process ) 292 292 { 293 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",293 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 294 294 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 295 295 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 325 325 } 326 326 327 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",327 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 328 328 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 329 329 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 336 336 process_t * process; 337 337 338 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",338 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 339 339 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 340 340 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 360 360 } 361 361 362 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",362 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 363 363 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 364 364 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 379 379 error_t * error ) // out 380 380 { 381 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",381 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 382 382 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 383 383 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 387 387 // initialise RPC descriptor header 388 388 rpc_desc_t rpc; 389 rpc.index = RPC_THREAD_USER_CREATE;390 rpc.response = 1;389 rpc.index = RPC_THREAD_USER_CREATE; 390 rpc.response = 1; 391 391 392 392 // set input arguments in RPC descriptor … … 403 403 *error = (error_t)rpc.args[5]; 404 404 405 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",405 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 406 406 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 407 407 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 421 421 error_t error; 422 422 423 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",423 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 424 424 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 425 425 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 442 442 sizeof(pthread_attr_t) ); 443 443 444 assert( (attr_copy.cxy == local_cxy) , __FUNCTION__ , "bad target cluster\n" );445 446 444 // call kernel function 447 445 error = thread_user_create( pid, … … 453 451 // set output arguments 454 452 thread_xp = XPTR( local_cxy , thread_ptr ); 455 hal_remote_swd( XPTR( client_cxy , &desc->args[ 1] ) , (uint64_t)error);456 hal_remote_swd( XPTR( client_cxy , &desc->args[ 2] ) , (uint64_t)thread_xp);457 458 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",453 hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)thread_xp ); 454 hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error ); 455 456 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 459 457 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 460 458 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 473 471 error_t * error ) // out 474 472 { 475 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",473 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 476 474 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 477 475 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 496 494 *error = (error_t)rpc.args[4]; 497 495 498 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",496 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 499 497 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 500 498 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 509 507 error_t error; 510 508 511 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",509 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 512 510 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 513 511 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 533 531 hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp ); 534 532 535 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",533 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 536 534 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 537 535 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 547 545 uint32_t sig_id ) // in 548 546 { 549 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",547 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 550 548 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 551 549 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 565 563 rpc_send_sync( cxy , &rpc ); 566 564 567 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",565 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 568 566 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 569 567 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 576 574 uint32_t sig_id; // signal index 577 575 578 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",576 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 579 577 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 580 578 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 591 589 signal_rise( process , sig_id ); 592 590 593 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",591 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 594 592 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 595 593 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 613 611 error_t * error ) // out 614 612 { 615 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",613 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 616 614 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 617 615 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 641 639 *error = (error_t)rpc.args[9]; 642 640 643 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",641 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 644 642 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 645 643 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 660 658 error_t error; 661 659 662 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",660 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 663 661 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 664 662 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 693 691 hal_remote_swd( XPTR( client_cxy , &desc->args[9] ) , (uint64_t)error ); 694 692 695 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",693 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 696 694 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 697 695 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 706 704 struct vfs_inode_s * inode ) 707 705 { 708 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",706 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 709 707 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 710 708 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 723 721 rpc_send_sync( cxy , &rpc ); 724 722 725 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",723 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 726 724 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 727 725 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 733 731 vfs_inode_t * inode; 734 732 735 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",733 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 736 734 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 737 735 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 747 745 vfs_inode_destroy( inode ); 748 746 749 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",747 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 750 748 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 751 749 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 764 762 error_t * error ) // out 765 763 { 766 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",764 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 767 765 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 768 766 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 787 785 *error = (error_t)rpc.args[4]; 788 786 789 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",787 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 790 788 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 791 789 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 803 801 char name_copy[CONFIG_VFS_MAX_NAME_LENGTH]; 804 802 805 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",803 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 806 804 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 807 805 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 829 827 hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error ); 830 828 831 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",829 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 832 830 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 833 831 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 843 841 vfs_dentry_t * dentry ) 844 842 { 845 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",843 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 846 844 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 847 845 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 860 858 rpc_send_sync( cxy , &rpc ); 861 859 862 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",860 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 863 861 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 864 862 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 870 868 vfs_dentry_t * dentry; 871 869 872 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",870 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 873 871 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 874 872 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 884 882 vfs_dentry_destroy( dentry ); 885 883 886 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",884 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 887 885 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 888 886 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 901 899 error_t * error ) // out 902 900 { 903 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",901 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 904 902 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 905 903 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 923 921 *error = (error_t)rpc.args[3]; 924 922 925 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",923 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 926 924 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 927 925 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 936 934 error_t error; 937 935 938 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",936 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 939 937 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 940 938 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 957 955 hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); 958 956 959 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",957 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 960 958 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 961 959 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 970 968 vfs_file_t * file ) 971 969 { 972 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",970 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 973 971 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 974 972 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 987 985 rpc_send_sync( cxy , &rpc ); 988 986 989 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",987 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 990 988 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 991 989 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 997 995 vfs_file_t * file; 998 996 999 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",997 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1000 998 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1001 999 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1011 1009 vfs_file_destroy( file ); 1012 1010 1013 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1011 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1014 1012 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1015 1013 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1027 1025 error_t * error ) // out 1028 1026 { 1029 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1027 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1030 1028 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1031 1029 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1049 1047 *error = (error_t)rpc.args[3]; 1050 1048 1051 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1049 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1052 1050 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1053 1051 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1064 1062 char name_copy[CONFIG_VFS_MAX_NAME_LENGTH]; 1065 1063 1066 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1064 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1067 1065 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1068 1066 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1087 1085 hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); 1088 1086 1089 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1087 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1090 1088 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1091 1089 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1101 1099 error_t * error ) // out 1102 1100 { 1103 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1101 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1104 1102 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1105 1103 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1121 1119 *error = (error_t)rpc.args[1]; 1122 1120 1123 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1121 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1124 1122 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1125 1123 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1132 1130 vfs_inode_t * inode; 1133 1131 1134 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1132 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1135 1133 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1136 1134 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1149 1147 hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error ); 1150 1148 1151 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1149 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1152 1150 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1153 1151 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1162 1160 mapper_t * mapper, // in 1163 1161 uint32_t first, // in 1164 uint32_t page,// in1162 uint32_t index, // in 1165 1163 uint32_t * cluster, // out 1166 1164 error_t * error ) // out 1167 1165 { 1168 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1166 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1169 1167 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1170 1168 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1180 1178 rpc.args[0] = (uint64_t)(intptr_t)mapper; 1181 1179 rpc.args[1] = (uint64_t)first; 1182 rpc.args[2] = (uint64_t) page;1180 rpc.args[2] = (uint64_t)index; 1183 1181 1184 1182 // register RPC request in remote RPC fifo … … 1189 1187 *error = (error_t)rpc.args[4]; 1190 1188 1191 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1189 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1192 1190 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1193 1191 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1199 1197 mapper_t * mapper; 1200 1198 uint32_t first; 1201 uint32_t page;1199 uint32_t index; 1202 1200 uint32_t cluster; 1203 1201 error_t error; 1204 1202 1205 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1203 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1206 1204 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1207 1205 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1214 1212 mapper = (mapper_t *)(intptr_t)hal_remote_lpt( XPTR( client_cxy , &desc->args[0] ) ); 1215 1213 first = (uint32_t) hal_remote_lw ( XPTR( client_cxy , &desc->args[1] ) ); 1216 page= (uint32_t) hal_remote_lw ( XPTR( client_cxy , &desc->args[2] ) );1214 index = (uint32_t) hal_remote_lw ( XPTR( client_cxy , &desc->args[2] ) ); 1217 1215 1218 1216 // call the kernel function 1219 error = fatfs_get_cluster( mapper , first , page, &cluster );1217 error = fatfs_get_cluster( mapper , first , index , &cluster ); 1220 1218 1221 1219 // set output argument … … 1223 1221 hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error ); 1224 1222 1225 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1223 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1226 1224 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1227 1225 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1239 1237 error_t * error ) // out 1240 1238 { 1241 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1239 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1242 1240 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1243 1241 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1261 1259 *error = (error_t)rpc.args[3]; 1262 1260 1263 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1261 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1264 1262 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1265 1263 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1275 1273 error_t error; 1276 1274 1277 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1275 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1278 1276 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1279 1277 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1295 1293 hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); 1296 1294 1297 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1295 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1298 1296 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1299 1297 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1309 1307 process_t * process, // in 1310 1308 vpn_t vpn, // in 1309 bool_t cow, // in 1311 1310 uint32_t * attr, // out 1312 1311 ppn_t * ppn, // out 1313 1312 error_t * error ) // out 1314 1313 { 1315 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1314 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1316 1315 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1317 1316 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1327 1326 rpc.args[0] = (uint64_t)(intptr_t)process; 1328 1327 rpc.args[1] = (uint64_t)vpn; 1328 rpc.args[2] = (uint64_t)cow; 1329 1329 1330 1330 // register RPC request in remote RPC fifo (blocking function) … … 1332 1332 1333 1333 // get output argument from rpc descriptor 1334 *attr = (uint32_t)rpc.args[ 2];1335 *ppn = (ppn_t)rpc.args[ 3];1336 *error = (error_t)rpc.args[ 4];1337 1338 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1334 *attr = (uint32_t)rpc.args[3]; 1335 *ppn = (ppn_t)rpc.args[4]; 1336 *error = (error_t)rpc.args[5]; 1337 1338 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1339 1339 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1340 1340 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1346 1346 process_t * process; 1347 1347 vpn_t vpn; 1348 bool_t cow; 1348 1349 uint32_t attr; 1349 1350 ppn_t ppn; 1350 1351 error_t error; 1351 1352 1352 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1353 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1353 1354 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1354 1355 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1361 1362 process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); 1362 1363 vpn = (vpn_t) hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); 1364 cow = (bool_t) hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) ); 1363 1365 1364 1366 // call local kernel function 1365 error = vmm_get_pte( process , vpn , &attr , &ppn );1367 error = vmm_get_pte( process , vpn , cow , &attr , &ppn ); 1366 1368 1367 1369 // set output argument "attr" & "ppn" to client RPC descriptor 1368 hal_remote_swd( XPTR( client_cxy , &desc->args[ 2] ) , (uint64_t)attr );1369 hal_remote_swd( XPTR( client_cxy , &desc->args[ 3] ) , (uint64_t)ppn );1370 hal_remote_swd( XPTR( client_cxy , &desc->args[ 4] ) , (uint64_t)error );1371 1372 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1370 hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)attr ); 1371 hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)ppn ); 1372 hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error ); 1373 1374 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1373 1375 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1374 1376 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1384 1386 xptr_t * buf_xp ) // out 1385 1387 { 1386 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1388 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1387 1389 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1388 1390 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1404 1406 *buf_xp = (xptr_t)rpc.args[1]; 1405 1407 1406 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1408 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1407 1409 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1408 1410 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1412 1414 void rpc_kcm_alloc_server( xptr_t xp ) 1413 1415 { 1414 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1416 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1415 1417 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1416 1418 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1433 1435 hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp ); 1434 1436 1435 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1437 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1436 1438 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1437 1439 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1447 1449 uint32_t kmem_type ) // in 1448 1450 { 1449 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1451 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1450 1452 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1451 1453 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1465 1467 rpc_send_sync( cxy , &rpc ); 1466 1468 1467 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1469 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1468 1470 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1469 1471 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1473 1475 void rpc_kcm_free_server( xptr_t xp ) 1474 1476 { 1475 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1477 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1476 1478 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1477 1479 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1491 1493 kmem_free( &req ); 1492 1494 1493 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1495 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1494 1496 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1495 1497 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1510 1512 error_t * error ) // out 1511 1513 { 1512 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1514 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1513 1515 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1514 1516 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1535 1537 *error = (error_t)rpc.args[6]; 1536 1538 1537 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1539 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1538 1540 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1539 1541 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1552 1554 error_t error; 1553 1555 1554 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1556 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1555 1557 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1556 1558 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1592 1594 hal_remote_swd( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)error ); 1593 1595 1594 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1596 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1595 1597 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1596 1598 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1607 1609 page_t ** page ) // out 1608 1610 { 1609 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1611 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1610 1612 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1611 1613 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1628 1630 *page = (page_t *)(intptr_t)rpc.args[2]; 1629 1631 1630 rpc_dmsg("\n[D MSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",1632 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1631 1633 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1632 1634 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1636 1638 void rpc_mapper_get_page_server( xptr_t xp ) 1637 1639 { 1638 rpc_dmsg("\n[D MSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",1640 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1639 1641 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1640 1642 CURRENT_THREAD->core->lid , hal_time_stamp() ); … … 1654 1656 hal_remote_swd( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page ); 1655 1657 1656 rpc_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1657 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1658 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1659 } 1660 1658 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1659 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1660 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1661 } 1662 1663 ///////////////////////////////////////////////////////////////////////////////////////// 1664 // [26] Marshaling functions attached to RPC_VMM_CREATE_VSEG 1665 ///////////////////////////////////////////////////////////////////////////////////////// 1666 1667 //////////////////////////////////////////////////////// 1668 void rpc_vmm_create_vseg_client( cxy_t cxy, 1669 struct process_s * process, 1670 vseg_type_t type, 1671 intptr_t base, 1672 uint32_t size, 1673 uint32_t file_offset, 1674 uint32_t file_size, 1675 xptr_t mapper_xp, 1676 cxy_t vseg_cxy, 1677 struct vseg_s ** vseg ) 1678 { 1679 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1680 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1681 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1682 1683 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1684 1685 // initialise RPC descriptor header 1686 rpc_desc_t rpc; 1687 rpc.index = RPC_VMM_CREATE_VSEG; 1688 rpc.response = 1; 1689 1690 // set input arguments in RPC descriptor 1691 rpc.args[0] = (uint64_t)(intptr_t)process; 1692 rpc.args[1] = (uint64_t)type; 1693 rpc.args[2] = (uint64_t)base; 1694 rpc.args[3] = (uint64_t)size; 1695 rpc.args[4] = (uint64_t)file_offset; 1696 rpc.args[5] = (uint64_t)file_size; 1697 rpc.args[6] = (uint64_t)mapper_xp; 1698 rpc.args[7] = (uint64_t)vseg_cxy; 1699 1700 // register RPC request in remote RPC fifo (blocking function) 1701 rpc_send_sync( cxy , &rpc ); 1702 1703 // get output values from RPC descriptor 1704 *vseg = (vseg_t *)(intptr_t)rpc.args[8]; 1705 1706 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1707 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1708 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1709 } 1710 1711 //////////////////////////////////////////// 1712 void rpc_vmm_create_vseg_server( xptr_t xp ) 1713 { 1714 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1715 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1716 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1717 1718 // get client cluster identifier and pointer on RPC descriptor 1719 cxy_t cxy = (cxy_t)GET_CXY( xp ); 1720 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 1721 1722 // get input arguments from client RPC descriptor 1723 process_t * process = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0])); 1724 vseg_type_t type = (vseg_type_t)(uint32_t)hal_remote_lwd( XPTR(cxy , &desc->args[1])); 1725 intptr_t base = (intptr_t) hal_remote_lwd( XPTR(cxy , &desc->args[2])); 1726 uint32_t size = (uint32_t) hal_remote_lwd( XPTR(cxy , &desc->args[3])); 1727 uint32_t file_offset = (uint32_t) hal_remote_lwd( XPTR(cxy , &desc->args[4])); 1728 uint32_t file_size = (uint32_t) hal_remote_lwd( XPTR(cxy , &desc->args[5])); 1729 xptr_t mapper_xp = (xptr_t) hal_remote_lwd( XPTR(cxy , &desc->args[6])); 1730 cxy_t vseg_cxy = (cxy_t)(uint32_t) hal_remote_lwd( XPTR(cxy , &desc->args[7])); 1731 1732 // call local kernel function 1733 vseg_t * vseg = vmm_create_vseg( process, 1734 type, 1735 base, 1736 size, 1737 file_offset, 1738 file_size, 1739 mapper_xp, 1740 vseg_cxy ); 1741 1742 // set output arguments into client RPC descriptor 1743 hal_remote_swd( XPTR( cxy , &desc->args[8] ) , (uint64_t)(intptr_t)vseg ); 1744 1745 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1746 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1747 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1748 } 1749 1750 ///////////////////////////////////////////////////////////////////////////////////////// 1751 // [27] Marshaling functions attached to RPC_SCHED_DISPLAY 1752 ///////////////////////////////////////////////////////////////////////////////////////// 1753 1754 //////////////////////////////////////////////////////// 1755 void rpc_sched_display_client( cxy_t cxy, 1756 lid_t lid) 1757 { 1758 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1759 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1760 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1761 1762 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1763 1764 // initialise RPC descriptor header 1765 rpc_desc_t rpc; 1766 rpc.index = RPC_SCHED_DISPLAY; 1767 rpc.response = 1; 1768 1769 // set input arguments in RPC descriptor 1770 rpc.args[0] = (uint64_t)lid; 1771 1772 // register RPC request in remote RPC fifo (blocking function) 1773 rpc_send_sync( cxy , &rpc ); 1774 1775 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1776 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1777 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1778 } 1779 1780 ////////////////////////////////////////// 1781 void rpc_sched_display_server( xptr_t xp ) 1782 { 1783 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1784 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1785 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1786 1787 // get client cluster identifier and pointer on RPC descriptor 1788 cxy_t cxy = (cxy_t)GET_CXY( xp ); 1789 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 1790 1791 // get input arguments from client RPC descriptor 1792 lid_t lid = (lid_t)hal_remote_lw( XPTR(cxy , &desc->args[0])); 1793 1794 // call local kernel function 1795 sched_display( lid ); 1796 1797 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 1798 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 1799 CURRENT_THREAD->core->lid , hal_time_stamp() ); 1800 } 1661 1801 1662 1802 /***************************************************************************************/ … … 1668 1808 rpc_desc_t * rpc ) 1669 1809 { 1670 uint32_t cores;1671 1810 error_t error; 1672 bool_t first; 1673 reg_t sr_save; 1674 1675 rpc_dmsg("\n[DMSG] %s : enter / client_cxy = %x / server_cxy = %x / cycle %d\n", 1676 __FUNCTION__ , local_cxy , server_cxy , hal_time_stamp() ); 1677 1678 // allocate and initialise an extended pointer on the RPC descriptor 1811 1812 thread_t * this = CURRENT_THREAD; 1813 core_t * core = this->core; 1814 1815 // register client thread pointer and core lid in RPC descriptor 1816 rpc->thread = this; 1817 rpc->lid = core->lid; 1818 1819 // build an extended pointer on the RPC descriptor 1679 1820 xptr_t desc_xp = XPTR( local_cxy , rpc ); 1680 1821 1681 1822 // get local pointer on rpc_fifo in remote cluster, with the 1682 // assumption that rpc_fifo pddresses are identical in all clusters1683 r pc_fifo_t * rf= &LOCAL_CLUSTER->rpc_fifo;1823 // assumption that local pointers are identical in all clusters 1824 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 1684 1825 1685 1826 // try to post an item in remote fifo … … 1687 1828 do 1688 1829 { 1689 error = remote_fifo_put_item( XPTR( server_cxy , &rf->fifo ), 1690 (uint64_t )desc_xp, 1691 &first ); 1830 error = remote_fifo_put_item( XPTR( server_cxy , rpc_fifo ), 1831 (uint64_t )desc_xp ); 1692 1832 if ( error ) 1693 1833 { … … 1695 1835 __FUNCTION__ , local_cxy , server_cxy ); 1696 1836 1697 if( thread_can_yield() ) sched_yield( NULL);1837 if( thread_can_yield() ) sched_yield(); 1698 1838 } 1699 1839 } 1700 1840 while( error ); 1701 1841 1702 rpc_dmsg("\n[DMSG] %s : RPC %l registered / server_cxy = %x / cycle %d\n", 1703 __FUNCTION__ , desc_xp , server_cxy , hal_time_stamp() ); 1842 hal_fence(); 1704 1843 1705 // send IPI to remote CP0, if this is the first RPC in remote FIFO, 1706 // and there is no CPU is in kernel mode in server cluster. 1707 if( first ) 1708 { 1709 // get number of cores in kernel mode in server cluster 1710 cores = hal_remote_lw( XPTR( server_cxy , &LOCAL_CLUSTER->cores_in_kernel ) ); 1711 1712 if( cores == 0 ) // no core in kernel mode in server 1713 { 1714 dev_pic_send_ipi( server_cxy , 0 ); 1715 1716 rpc_dmsg("\n[DMSG] %s : IPI sent / client_cxy = %x / server_cxy = %x\n", 1717 __FUNCTION__, local_cxy , server_cxy ); 1718 } 1719 } 1720 1721 // enable IRQs to allow incoming RPC and avoid deadlock 1722 hal_enable_irq( &sr_save ); 1723 1724 // the server thread poll the response slot until RPC completed 1725 // TODO this could be replaced by a descheduling policy... [AG] 1726 while( rpc->response ) asm volatile( "nop" ); 1727 1728 // restore IRQs 1729 hal_restore_irq( sr_save ); 1730 1731 rpc_dmsg("\n[DMSG] %s : completed / client_cxy = %x / server_cxy = %x / cycle %d\n", 1732 __FUNCTION__ , local_cxy , server_cxy , hal_time_stamp() ); 1733 1844 // send IPI to the remote core corresponding to the client core 1845 dev_pic_send_ipi( server_cxy , core->lid ); 1846 1847 // wait RPC completion: 1848 // - busy waiting policy during kernel_init, or if threads cannot yield 1849 // - block and deschedule in all other cases 1850 1851 if( (this->type == THREAD_IDLE) || (thread_can_yield() == false) ) // busy waiting 1852 { 1853 1854 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s busy waiting after registering RPC\n" 1855 " rpc = %d / server = %x / cycle %d\n", 1856 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) , 1857 rpc->index , server_cxy , hal_time_stamp() ); 1858 1859 while( rpc->response ) hal_fixed_delay( 100 ); 1860 1861 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s exit after RPC completion\n", 1862 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ); 1863 1864 } 1865 else // block & deschedule 1866 { 1867 1868 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s deschedule after registering RPC\n" 1869 " rpc = %d / server = %x / cycle %d\n", 1870 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) , 1871 rpc->index , server_cxy , hal_time_stamp() ); 1872 1873 thread_block( this , THREAD_BLOCKED_RPC ); 1874 sched_yield(); 1875 1876 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s resumes after RPC completion\n", 1877 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ); 1878 1879 } 1880 1881 // check response available 1882 assert( (rpc->response == 0) , __FUNCTION__, "illegal RPC response\n" ); 1883 1884 // acknowledge the IPI sent by the server 1885 dev_pic_ack_ipi(); 1886 1734 1887 } // end rpc_send_sync() 1735 1888 … … 1740 1893 /***************************************************************************************/ 1741 1894 1742 /////////////////////////////////////////// 1743 void rpc_fifo_init( rpc_fifo_t * rpc_fifo ) 1744 { 1745 rpc_fifo->count = 0; 1746 rpc_fifo->owner = 0; 1747 local_fifo_init( &rpc_fifo->fifo ); 1748 } 1749 1750 ///////////////////////////////////////////// 1751 void rpc_execute_all( rpc_fifo_t * rpc_fifo ) 1752 { 1753 xptr_t xp; // extended pointer on RPC descriptor 1754 uint32_t count; // handled RPC request counter 1755 thread_t * this; // pointer on this RPC thread 1756 core_t * core; // pointer on core running this thread 1757 rpc_desc_t * desc; // pointer on RPC descriptor 1758 uint32_t index; // RPC index 1759 cxy_t client_cxy; // client cluster identifier 1760 error_t error; 1761 1762 this = CURRENT_THREAD; 1763 core = this->core; 1764 count = 0; 1765 1766 rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1767 __FUNCTION__, this->trdid, local_cxy, core->lid , hal_time_stamp() ); 1895 //////////////// 1896 void rpc_check() 1897 { 1898 error_t error; 1899 thread_t * thread; 1900 uint32_t sr_save; 1901 1902 bool_t found = false; 1903 thread_t * this = CURRENT_THREAD; 1904 core_t * core = this->core; 1905 scheduler_t * sched = &core->scheduler; 1906 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 1907 1908 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s / cycle %d\n", 1909 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() ); 1910 1911 // interrupted thread not preemptable during RPC chek 1912 hal_disable_irq( &sr_save ); 1913 1914 // check RPC FIFO not empty and no RPC thread handling it 1915 if( (rpc_fifo->owner == 0) && (local_fifo_is_empty(rpc_fifo) == false) ) 1916 { 1917 // search one non blocked RPC thread 1918 list_entry_t * iter; 1919 LIST_FOREACH( &sched->k_root , iter ) 1920 { 1921 thread = LIST_ELEMENT( iter , thread_t , sched_list ); 1922 if( (thread->type == THREAD_RPC) && (thread->blocked == 0 ) ) 1923 { 1924 found = true; 1925 break; 1926 } 1927 } 1928 1929 // create new RPC thread if not found 1930 if( found == false ) 1931 { 1932 error = thread_kernel_create( &thread, 1933 THREAD_RPC, 1934 &rpc_thread_func, 1935 NULL, 1936 this->core->lid ); 1937 if( error ) 1938 { 1939 printk("\n[WARNING] in %s : no memory for new RPC thread in cluster %x\n", 1940 __FUNCTION__ , local_cxy ); 1941 } 1942 else 1943 { 1944 // unblock created RPC thread 1945 thread->blocked = 0; 1946 1947 // update core descriptor counter 1948 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 ); 1949 1950 grpc_dmsg("\n[DBG] %s : core [%x,%d] creates a new RPC thread %x / cycle %d\n", 1951 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() ); 1952 1953 } 1954 } 1955 } 1956 1957 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s deschedules / cycle %d\n", 1958 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() ); 1959 1960 // interrupted thread deschedule always 1961 sched_yield(); 1962 1963 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s resume / cycle %d\n", 1964 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() ); 1965 1966 // interrupted thread restore IRQs after resume 1967 hal_restore_irq( sr_save ); 1968 1969 } // end rpc_check() 1970 1971 1972 ////////////////////// 1973 void rpc_thread_func() 1974 { 1975 uint32_t count; // handled RPC requests counter 1976 error_t empty; // local RPC fifo state 1977 xptr_t desc_xp; // extended pointer on RPC request 1978 cxy_t desc_cxy; // RPC request cluster (client) 1979 rpc_desc_t * desc_ptr; // RPC request local pointer 1980 uint32_t index; // RPC request index 1981 uint32_t responses; // number of responses received by client 1982 thread_t * thread_ptr; // local pointer on client thread 1983 lid_t core_lid; // local index of client core 1768 1984 1769 // handle up to CONFIG_RPC_PENDING_MAX requests before exit 1770 do 1771 { 1772 error = local_fifo_get_item( &rpc_fifo->fifo, (uint64_t *)&xp ); 1773 1774 if ( error == 0 ) // One RPC request successfully extracted from RPC_FIFO 1985 // makes RPC thread not preemptable 1986 hal_disable_irq( NULL ); 1987 1988 thread_t * this = CURRENT_THREAD; 1989 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 1990 1991 // two embedded loops: 1992 // - external loop : "infinite" RPC thread 1993 // - internal loop : handle up to CONFIG_RPC_PENDING_MAX RPC requests 1994 1995 while(1) // external loop 1996 { 1997 // try to take RPC_FIFO ownership 1998 if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) ) 1775 1999 { 1776 // get client cluster identifier and pointer on RPC descriptor 1777 client_cxy = (cxy_t)GET_CXY( xp ); 1778 desc = (rpc_desc_t *)GET_PTR( xp ); 1779 1780 // get rpc index from RPC descriptor 1781 index = hal_remote_lw( XPTR( client_cxy , &desc->index ) ); 1782 1783 rpc_dmsg("\n[DMSG] %s : thread %x on core [%x,%d] / rpc = %d\n", 1784 __FUNCTION__ , this->trdid , core->lid , local_cxy , index ); 1785 1786 // call the relevant server function 1787 rpc_server[index]( xp ); 1788 1789 // increment handled RPC counter 1790 count++; 1791 1792 // notify RPC completion as required 1793 hal_remote_atomic_add( XPTR( client_cxy , &desc->response ) , -1 ); 1794 } 2000 // initializes RPC requests counter 2001 count = 0; 2002 2003 // acknowledge local IPI 2004 dev_pic_ack_ipi(); 2005 2006 // exit internal loop in three cases: 2007 // - RPC fifo is empty 2008 // - ownership has been lost (because descheduling) 2009 // - max number of RPCs is reached 2010 while( 1 ) // internal loop 2011 { 2012 empty = local_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp ); 2013 2014 if ( empty == 0 ) // one RPC request found 2015 { 2016 // get client cluster and pointer on RPC descriptor 2017 desc_cxy = (cxy_t)GET_CXY( desc_xp ); 2018 desc_ptr = (rpc_desc_t *)GET_PTR( desc_xp ); 2019 2020 // get rpc index from RPC descriptor 2021 index = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->index ) ); 2022 2023 grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / starts rpc %d / cycle %d\n", 2024 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() ); 2025 2026 // call the relevant server function 2027 rpc_server[index]( desc_xp ); 2028 2029 grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / completes rpc %d / cycle %d\n", 2030 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() ); 2031 2032 // increment handled RPC counter 2033 count++; 2034 2035 // decrement response counter in RPC descriptor 2036 responses = hal_remote_atomic_add(XPTR( desc_cxy, &desc_ptr->response ), -1); 2037 2038 // unblock client thread and send IPI to client core if last response 2039 if( responses == 1 ) 2040 { 2041 // get pointer on client thread and unblock it 2042 thread_ptr = (thread_t *)hal_remote_lpt(XPTR(desc_cxy,&desc_ptr->thread)); 2043 thread_unblock( XPTR(desc_cxy,thread_ptr) , THREAD_BLOCKED_RPC ); 2044 2045 hal_fence(); 2046 2047 // get client core lid and send IPI 2048 core_lid = hal_remote_lw(XPTR(desc_cxy, &desc_ptr->lid)); 2049 dev_pic_send_ipi( desc_cxy , core_lid ); 2050 } 2051 } 1795 2052 1796 // exit loop in three cases: 1797 // - fifo is empty 1798 // - look has been released (because descheduling) 1799 // - max number of RPCs has been reached 1800 if( error || 1801 (rpc_fifo->owner != this->trdid) || 1802 (count > CONFIG_RPC_PENDING_MAX) ) break; 1803 } 1804 while( 1 ); 1805 1806 // update RPC_FIFO global counter 1807 rpc_fifo->count += count; 1808 1809 } // end rpc_execute_all() 2053 // chek exit condition 2054 if( local_fifo_is_empty( rpc_fifo ) || 2055 (rpc_fifo->owner != this->trdid) || 2056 (count >= CONFIG_RPC_PENDING_MAX) ) break; 2057 } // end internal loop 2058 2059 // release rpc_fifo ownership if not lost 2060 if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0; 2061 } 2062 2063 // sucide if too many RPC threads in cluster 2064 if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX ) 2065 { 2066 2067 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) suicide at cycle %d\n", 2068 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 2069 2070 // update RPC threads counter 2071 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 ); 2072 2073 // suicide 2074 thread_exit(); 2075 } 2076 2077 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) deschedules / cycle %d\n", 2078 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 2079 2080 // deschedule without blocking 2081 sched_yield(); 2082 2083 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) resumes / cycle %d\n", 2084 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 2085 2086 } // end external loop 2087 2088 } // end rpc_thread_func() 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 /* deprecated [AG] 29/09/2017 1810 2099 1811 2100 //////////////////////////////////////////////////// 1812 error_t rpc_activate_thread( r pc_fifo_t * rpc_fifo )2101 error_t rpc_activate_thread( remote_fifo_t * rpc_fifo ) 1813 2102 { 1814 2103 core_t * core; … … 1827 2116 1828 2117 assert( (this->trdid == rpc_fifo->owner) , __FUNCTION__ , 1829 2118 "calling thread is not RPC_FIFO owner\n" ); 1830 2119 1831 2120 // makes the calling thread not preemptable … … 1833 2122 hal_disable_irq( &sr_save ); 1834 2123 1835 // search a free RPC thread (must be in THREAD_BLOCKED_IDLE state) 2124 grpc_dmsg("\n[DBG] %s : core[%x,%d] enter at cycle %d\n", 2125 __FUNCTION__ , local_cxy , core->lid , hal_time_stamp() ); 2126 2127 // search one non blocked RPC thread 1836 2128 list_entry_t * iter; 1837 2129 LIST_FOREACH( &sched->k_root , iter ) 1838 2130 { 1839 2131 thread = LIST_ELEMENT( iter , thread_t , sched_list ); 1840 if( (thread->type == THREAD_RPC) && (thread->blocked == THREAD_BLOCKED_IDLE) )2132 if( (thread->type == THREAD_RPC) && (thread->blocked == 0 ) ) 1841 2133 { 1842 2134 found = true; … … 1845 2137 } 1846 2138 1847 if( found ) // activate this idleRPC thread2139 if( found == false ) // create new RPC thread 1848 2140 { 1849 // unblock it1850 thread->blocked = 0;1851 1852 rpc_dmsg("\n[DMSG] %s : activate RPC thread %x on core [%x,%d] / cycle %d\n",1853 __FUNCTION__ , thread , core->gid , local_cxy , hal_time_stamp() );1854 }1855 else // create a new RPC thread1856 {1857 // create new thread1858 2141 error = thread_kernel_create( &thread, 1859 2142 THREAD_RPC, … … 1869 2152 } 1870 2153 1871 // unblock newthread2154 // unblock thread 1872 2155 thread->blocked = 0; 1873 2156 … … 1875 2158 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 ); 1876 2159 1877 rpc_dmsg("\n[DMSG] %s : create RPC thread %x on core [%x,%d] / cycle %d\n", 1878 __FUNCTION__ , thread->trdid, local_cxy, core->lid, hal_time_stamp() ); 2160 grpc_dmsg("\n[DBG] %s : core [%x,%d] creates RPC thread %x at cycle %d\n", 2161 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() ); 2162 1879 2163 } 1880 1881 // update owner in rpc_fifo 2164 else // create a new RPC thread 2165 { 2166 2167 grpc_dmsg("\n[DBG] %s : core[%x,%d] activates RPC thread %x at cycle %d\n", 2168 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() ); 2169 2170 } 2171 2172 // update rpc_fifo owner 1882 2173 rpc_fifo->owner = thread->trdid; 1883 2174 1884 // current thread switch to RPC thread1885 sched_yield( thread);2175 // current thread deschedule 2176 sched_yield(); 1886 2177 1887 2178 // restore IRQs for the calling thread … … 1893 2184 } // end rpc_activate_thread() 1894 2185 1895 //////////////// //1896 bool_trpc_check()2186 //////////////// 2187 void rpc_check() 1897 2188 { 1898 2189 thread_t * this = CURRENT_THREAD; 1899 r pc_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;2190 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 1900 2191 error_t error; 1901 2192 1902 rpc_dmsg("\n[DMSG] %s : enter / thread %x / cluster %x /cycle %d\n",1903 __FUNCTION__ , this->trdid , local_cxy, hal_time_stamp() );2193 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / enter at cycle %d\n", 2194 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , hal_time_stamp() ); 1904 2195 1905 2196 // calling thread does nothing if light lock already taken or FIFO empty 1906 2197 if( (rpc_fifo->owner != 0) || (local_fifo_is_empty( &rpc_fifo->fifo )) ) 1907 2198 { 1908 rpc_dmsg("\n[DMSG] %s : exit do nothing / thread %x / cluster %x / cycle %d\n", 1909 __FUNCTION__ , this->trdid , local_cxy , hal_time_stamp() ); 1910 1911 return false; 2199 2200 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / exit do nothing at cycle %d\n", 2201 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , hal_time_stamp() ); 2202 2203 return; 1912 2204 } 1913 2205 … … 1922 2214 1923 2215 printk("\n[ERROR] in %s : no memory to create a RPC thread for core %d" 1924 1925 2216 " in cluster %x => do nothing\n", 2217 __FUNCTION__ , CURRENT_CORE->lid , local_cxy ); 1926 2218 } 1927 2219 1928 rpc_dmsg("\n[DMSG] %s : exit after RPC thread activation / " 1929 "thread %x / cluster %x / cycle %d\n", 1930 __FUNCTION__ , this->trdid , local_cxy , hal_time_stamp() ); 1931 1932 return true; 2220 return; 1933 2221 } 1934 2222 else // light lock taken by another thread 1935 2223 { 1936 rpc_dmsg("\n[DMSG] %s : exit do nothing / thread %x / cluster %x / cycle %d\n", 1937 __FUNCTION__ , this->trdid , local_cxy , hal_time_stamp() ); 1938 1939 return false; 2224 2225 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / exit do nothing at cycle %d\n", 2226 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , hal_time_stamp() ); 2227 2228 return; 1940 2229 } 1941 2230 } // end rpc_check() … … 1949 2238 1950 2239 thread_t * this = CURRENT_THREAD; 1951 rpc_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 1952 1953 rpc_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 1954 __FUNCTION__, this->trdid, local_cxy, this->core->lid, hal_time_stamp() ); 1955 1956 // this infinite loop is not preemptable 1957 // the RPC thread deschedule only when the RPC_FIFO is empty 2240 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 2241 1958 2242 while(1) 1959 2243 { 1960 2244 // check fifo ownership (ownership should be given by rpc_activate() 1961 if( this->trdid != rpc_fifo->owner ) 1962 { 1963 panic("thread %x on core[%x,%d] not owner of RPC_FIFO", 1964 this->trdid, local_cxy, this->core->lid ); 1965 } 2245 assert( (this->trdid == rpc_fifo->owner) , __FUNCTION__ , 2246 "thread %x on core[%x,%d] not owner of RPC_FIFO / owner = %x\n", 2247 this->trdid, local_cxy, this->core->lid , rpc_fifo->owner ); 1966 2248 1967 2249 // executes pending RPC(s) 1968 2250 rpc_execute_all( rpc_fifo ); 1969 2251 1970 // release rpc_fifo ownership (can be lost during RPC execution) 2252 // release rpc_fifo ownership if required 2253 // (this ownership can be lost during RPC execution) 1971 2254 if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0; 1972 2255 1973 1974 // block and deschedule or sucide 1975 if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX ) 2256 // deschedule or sucide 2257 if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX ) // suicide 1976 2258 { 1977 rpc_dmsg("\n[DMSG] %s : RPC thread %x on core[%x,%d] suicide / cycle %d\n", 1978 __FUNCTION__, this->trdid, local_cxy, this->core->lid, hal_time_stamp() ); 2259 2260 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / suicide at cycle %d\n", 2261 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 1979 2262 1980 2263 // update core descriptor counter … … 1984 2267 thread_exit(); 1985 2268 } 1986 else 2269 else // deschedule 1987 2270 { 1988 rpc_dmsg("\n[DMSG] %s : RPC thread %x on core[%x,%d] blocks / cycle %d\n", 1989 __FUNCTION__, this->trdid, local_cxy, this->core->lid, hal_time_stamp() ); 1990 1991 thread_block( this , THREAD_BLOCKED_IDLE ); 1992 sched_yield( NULL ); 1993 1994 rpc_dmsg("\n[DMSG] %s : RPC thread %x wake up on core[%x,%d] / cycle %d\n", 1995 __FUNCTION__, this->trdid, local_cxy, this->core->lid, hal_time_stamp() ); 2271 2272 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / deschedule at cycle %d\n", 2273 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 2274 2275 sched_yield(); 2276 2277 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / wake up at cycle %d\n", 2278 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 2279 1996 2280 } 1997 2281 } // end while 1998 2282 } // end rpc_thread_func() 1999 2283 2284 */ 2285 2286 -
trunk/kernel/kern/rpc.h
r401 r407 30 30 #include <bits.h> 31 31 #include <spinlock.h> 32 #include <vseg.h> 32 33 #include <remote_fifo.h> 33 34 … … 82 83 RPC_MAPPER_MOVE_BUFFER = 24, 83 84 RPC_MAPPER_GET_PAGE = 25, 85 RPC_VMM_CREATE_VSEG = 26, 86 RPC_SCHED_DISPLAY = 27, 84 87 85 88 RPC_MAX_INDEX = 30, … … 100 103 typedef struct rpc_desc_s 101 104 { 102 rpc_index_t index; // index of requested RPC service 103 volatile uint32_t response; // response valid when 0 104 uint64_t args[10]; // input/output arguments buffer 105 rpc_index_t index; /*! index of requested RPC service */ 106 volatile uint32_t response; /*! response valid when 0 */ 107 struct thread_s * thread; /*! local pointer on client thread */ 108 uint32_t lid; /*! index of core running the calling thread */ 109 uint64_t args[10]; /*! input/output arguments buffer */ 105 110 } 106 111 rpc_desc_t; 107 108 /***********************************************************************************109 * This structure defines the RPC fifo, containing a remote_fifo, the owner RPC110 * thread TRDID (used as a light lock), and the intrumentation counter.111 *112 * Implementation note: the TRDID is a good owner identifier, because all113 * RPC threads in a given cluster belong to the same process_zero kernel process,114 * and RPC threads cannot have local index LTID = 0.115 **********************************************************************************/116 117 typedef struct rpc_fifo_s118 {119 trdid_t owner; // owner thread / 0 if no owner120 uint64_t count; // total number of received RPCs (instrumentation)121 remote_fifo_t fifo; // embedded remote fifo122 }123 rpc_fifo_t;124 125 112 126 113 /**********************************************************************************/ … … 149 136 150 137 /*********************************************************************************** 151 * This function initialises the local RPC fifo and the lock protecting readers.152 * The number of slots is defined by the CONFIG_REMOTE_FIFO_SLOTS parameter.153 * Each slot contains an extended pointer on the RPC descriptor.154 ***********************************************************************************155 * @ rf : pointer on the local RPC fifo.156 **********************************************************************************/157 void rpc_fifo_init( rpc_fifo_t * rf );158 159 /***********************************************************************************160 138 * This function is the entry point for RPC handling on the server side. 161 * It is executed by a core receiving an IPI .162 * It checks the RPC fifo, try to take the light-lock and activates (or creates)163 * an RPC thread in case of success.164 * **********************************************************************************165 * @ returns true if success / false otherwise.166 **********************************************************************************/ 167 bool_trpc_check();139 * It is executed by a core receiving an IPI, and each time the core enters, 140 * or exit the kernel to handle . 141 * It does nothing and return if the RPC_FIFO is empty. 142 * The calling thread checks if it exist at least one non-blocked RPC thread, 143 * creates a new RPC if required, and deschedule to allow the RPC thead to execute. 144 **********************************************************************************/ 145 void rpc_check(); 168 146 169 147 /*********************************************************************************** 170 148 * This function contains the loop to execute all pending RPCs on the server side. 171 * It should be called with irq disabled and after light lock acquisition. 149 * It is called by the rpc_thread_func() function with irq disabled, and after 150 * RPC_FIFO ownership acquisition. 172 151 *********************************************************************************** 173 152 * @ rpc_fifo : pointer on the local RPC fifo 174 153 **********************************************************************************/ 175 void rpc_execute_all( rpc_fifo_t * rpc_fifo ); 176 177 /********************************************************************************** 178 * This function is called by any thread running on any core in any cluster, 179 * that detected a non-empty RPC_FIFO and got the RPC_FIFO ownership. 180 * It activates one RPC thread, and immediately switches to the RPC thread. 181 * It gets the first free RPC thread from the core free-list, or creates a new one 182 * when the core free-list is empty. 183 *********************************************************************************** 184 * @ rpc_fifo : pointer on the non-empty RPC fifo. 185 * @ return 0 if success / return ENOMEM if error. 186 **********************************************************************************/ 187 error_t rpc_activate_thread( rpc_fifo_t * rpc_fifo ); 188 189 /*********************************************************************************** 190 * This function contains the infinite loop executed by each RPC thread. 154 void rpc_execute_all( remote_fifo_t * rpc_fifo ); 155 156 /*********************************************************************************** 157 * This function contains the infinite loop executed by a RPC thread. 191 158 **********************************************************************************/ 192 159 void rpc_thread_func(); … … 266 233 *********************************************************************************** 267 234 * @ cxy : server cluster identifier. 268 * @ attr : [in] pointer on pthread_attr_t in client cluster.269 * @ thread_xp : [out] pointer onbuffer for thread extended pointer.235 * @ attr : [in] local pointer on pthread_attr_t in client cluster. 236 * @ thread_xp : [out] buffer for thread extended pointer. 270 237 * @ error : [out] error status (0 if success). 271 238 **********************************************************************************/ … … 274 241 void * start_func, 275 242 void * start_arg, 276 struct pthread_attr_s* attr,243 pthread_attr_t * attr, 277 244 xptr_t * thread_xp, 278 245 error_t * error ); … … 499 466 500 467 /*********************************************************************************** 501 * [21] The RPC_VMM_GET_PTE returns in the "ppn" and "attr"arguments the PTE value502 * for a given VPN in a given process.468 * [21] The RPC_VMM_GET_PTE returns in the <ppn> and <attr> arguments the PTE value 469 * for a given <vpn> in a given <process> (page_fault or copy_on_write event). 503 470 * The server cluster is supposed to be the reference cluster, and the vseg 504 471 * containing the VPN must be registered in the reference VMM. 505 * It returns an error if physical memory cannot be allocated for the PTE2,472 * It returns an error if physical memory cannot be allocated for the missing PTE2, 506 473 * or for the missing page itself. 507 474 *********************************************************************************** … … 509 476 * @ process : [in] pointer on process descriptor in server cluster. 510 477 * @ vaddr : [in] virtual address to be searched. 478 * @ cow : [in] "copy_on_write" event if true / "page_fault" event if false. 511 479 * @ attr : [out] address of buffer for attributes. 512 480 * @ ppn : [out] address of buffer for PPN. … … 516 484 struct process_s * process, 517 485 vpn_t vpn, 486 bool_t cow, 518 487 uint32_t * attr, 519 488 ppn_t * ppn, … … 601 570 void rpc_mapper_get_page_server( xptr_t xp ); 602 571 572 /*********************************************************************************** 573 * [26] The RPC_VMM_CREATE_VSEG allows a client thread to request the remote 574 * reference cluster of a given process to allocate and register in the reference 575 * process VMM a new vseg descriptor. 576 * On the server side, this RPC uses the vmm_create_vseg() function, and returns 577 * to the client the local pointer on the created vseg descriptor. 578 *********************************************************************************** 579 * @ cxy : server cluster identifier. 580 * @ process : [in] local pointer on process descriptor in server. 581 * @ type : [in] vseg type. 582 * @ base : [in] base address (unused for dynamically allocated vsegs). 583 * @ size : [in] number of bytes. 584 * @ file_offset : [in] offset in file (for CODE, DATA, FILE types). 585 * @ file_size : [in] can be smaller than size for DATA type. 586 * @ mapper_xp : [in] extended pointer on mapper (for CODE, DATA, FILE types). 587 * @ vseg_cxy : [in] target cluster for mapping (if not data type). 588 * @ vseg : [out] local pointer on vseg descriptor / NULL if failure. 589 **********************************************************************************/ 590 void rpc_vmm_create_vseg_client( cxy_t cxy, 591 struct process_s * process, 592 vseg_type_t type, 593 intptr_t base, 594 uint32_t size, 595 uint32_t file_offset, 596 uint32_t file_size, 597 xptr_t mapper_xp, 598 cxy_t vseg_cxy, 599 struct vseg_s ** vseg ); 600 601 void rpc_vmm_create_vseg_server( xptr_t xp ); 602 603 /*********************************************************************************** 604 * [27] The RPC_SCHED_DISPLAY allows a client thread to request the display 605 * of a remote scheduler, identified by the <lid> argument. 606 *********************************************************************************** 607 * @ cxy : server cluster identifier. 608 * @ lid : [in] local index of target core in client cluster. 609 **********************************************************************************/ 610 void rpc_sched_display_client( cxy_t cxy, 611 lid_t lid ); 612 613 void rpc_sched_display_server( xptr_t xp ); 614 603 615 #endif -
trunk/kernel/kern/scheduler.c
r406 r407 24 24 #include <kernel_config.h> 25 25 #include <hal_types.h> 26 #include <hal_switch.h> 26 27 #include <hal_irqmask.h> 27 28 #include <hal_context.h> … … 38 39 39 40 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c file 40 41 extern uint32_t switch_save_sr[]; // allocated in kernel_init.c file 41 42 42 43 //////////////////////////////// … … 127 128 } // end sched_remove() 128 129 129 ///////////////////////////////////////////130 void sched_kill_thread( thread_t * thread )131 {132 // check thread locks133 if( thread_can_yield() == false )134 {135 panic("thread %x in process %x on core[%x][%d]"136 " did not released all locks",137 thread->trdid , thread->process->pid,138 local_cxy , thread->core->lid );139 }140 141 // remove thread from scheduler142 sched_remove_thread( thread );143 144 // reset the THREAD_SIG_KILL signal145 thread_reset_signal( thread , THREAD_SIG_KILL );146 147 } // end sched_kill_thread()148 149 130 //////////////////////////////////////// 150 131 thread_t * sched_select( core_t * core ) … … 154 135 scheduler_t * sched = &core->scheduler; 155 136 156 sched_dmsg("\n[DMSG] %s : enter core[%x,%d] / cycle %d\n",157 __FUNCTION__ , local_cxy , core->lid , hal_time_stamp() );158 159 137 // take lock protecting sheduler lists 160 138 spinlock_lock( &sched->lock ); … … 163 141 list_entry_t * last; 164 142 165 // first : scan the kernel threads list if not empty143 // first loop : scan the kernel threads list if not empty 166 144 if( list_is_empty( &sched->k_root ) == false ) 167 145 { … … 179 157 thread = LIST_ELEMENT( current , thread_t , sched_list ); 180 158 181 // return thread if not idle_thread and runnable182 if( (thread->type != THREAD_IDLE) && (thread->blocked == 0) )159 // analyse kernel thread type 160 switch( thread->type ) 183 161 { 184 // release lock 185 spinlock_unlock( &sched->lock ); 186 187 sched_dmsg("\n[DMSG] %s : exit core[%x,%d] / k_thread = %x / cycle %d\n", 188 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() ); 189 190 return thread; 191 } 162 case THREAD_IDLE: // skip IDLE thread 163 break; 164 165 case THREAD_RPC: // RPC thread if non blocked and FIFO non-empty 166 if( (thread->blocked == 0) && 167 (local_fifo_is_empty( &LOCAL_CLUSTER->rpc_fifo ) == 0) ) 168 { 169 spinlock_unlock( &sched->lock ); 170 return thread; 171 } 172 break; 173 174 default: // DEV thread if non blocked 175 if( thread->blocked == 0 ) 176 { 177 spinlock_unlock( &sched->lock ); 178 return thread; 179 } 180 break; 181 } // end switch type 192 182 } 193 183 while( current != last ); 194 184 } 195 185 196 // second : scan the user threads list if not empty186 // second loop : scan the user threads list if not empty 197 187 if( list_is_empty( &sched->u_root ) == false ) 198 188 { … … 213 203 if( thread->blocked == 0 ) 214 204 { 215 // release lock216 205 spinlock_unlock( &sched->lock ); 217 218 sched_dmsg("\n[DMSG] %s : exit core[%x,%d] / u_thread = %x / cycle %d\n",219 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );220 206 return thread; 221 207 } … … 224 210 } 225 211 226 // release lock212 // third : return idle thread if no runnable thread 227 213 spinlock_unlock( &sched->lock ); 228 229 sched_dmsg("\n[DMSG] %s : exit core[%x,%d] / idle = %x / cycle %d\n",230 __FUNCTION__ , local_cxy , core->lid , sched->idle->trdid , hal_time_stamp() );231 232 // third : return idle thread if no runnable thread233 214 return sched->idle; 234 215 235 216 } // end sched_select() 217 218 /////////////////////////////////////////// 219 void sched_kill_thread( thread_t * thread ) 220 { 221 // check locks 222 if( thread_can_yield() == false ) 223 { 224 panic("locks not released for thread %x in process %x on core[%x][%d]", 225 thread->trdid , thread->process->pid, local_cxy , thread->core->lid ); 226 } 227 228 // remove thread from scheduler 229 sched_remove_thread( thread ); 230 231 // reset the THREAD_SIG_KILL signal 232 thread_reset_signal( thread , THREAD_SIG_KILL ); 233 234 // detached thread can suicide 235 if( thread->signals & THREAD_SIG_SUICIDE ) 236 { 237 assert( (thread->flags & THREAD_FLAG_DETACHED), __FUNCTION__, 238 "thread must be detached in case of suicide\n" ); 239 240 // remove thread from process 241 process_remove_thread( thread ); 242 243 // release memory for thread descriptor 244 thread_destroy( thread ); 245 } 246 } // end sched_kill_thread() 236 247 237 248 ////////////////////////////////////////// … … 242 253 scheduler_t * sched = &core->scheduler; 243 254 244 sched_dmsg("\n[DMSG] %s : enter / thread %x on core[%x,%d]\n",245 __FUNCTION__, CURRENT_THREAD->trdid , local_cxy , core->lid );246 247 255 // take lock protecting threads lists 248 256 spinlock_lock( &sched->lock ); … … 252 260 { 253 261 thread = LIST_ELEMENT( iter , thread_t , sched_list ); 254 if( thread->signals & THREAD_SIG_KILL )sched_kill_thread( thread );262 if( thread->signals ) sched_kill_thread( thread ); 255 263 } 256 264 … … 259 267 { 260 268 thread = LIST_ELEMENT( iter , thread_t , sched_list ); 261 if( thread->signals & THREAD_SIG_KILL )sched_kill_thread( thread );269 if( thread->signals ) sched_kill_thread( thread ); 262 270 } 263 271 … … 265 273 spinlock_unlock( &sched->lock ); 266 274 267 sched_dmsg("\n[DMSG] %s : exit / thread %x on core[%x,%d]\n",268 __FUNCTION__, CURRENT_THREAD->trdid , local_cxy , core->lid );269 270 275 } // end sched_handle_signals() 271 276 272 /////////////////////////////////// 273 void sched_yield( thread_t * next ) 274 { 275 reg_t sr_save; 276 277 ////////////////////////////////////// 278 void sched_update( thread_t * current, 279 thread_t * next ) 280 { 281 scheduler_t * sched = ¤t->core->scheduler; 282 283 if( current->type == THREAD_USER ) sched->u_last = ¤t->sched_list; 284 else sched->k_last = ¤t->sched_list; 285 286 sched->current = next; 287 } 288 289 ////////////////// 290 void sched_yield() 291 { 292 thread_t * next; 277 293 thread_t * current = CURRENT_THREAD; 278 core_t * core = current->core; 279 scheduler_t * sched = &core->scheduler; 280 281 sched_dmsg("\n[DMSG] %s : thread %x on core[%x,%d] enter / cycle %d\n", 282 __FUNCTION__, current->trdid, local_cxy, core->lid, hal_time_stamp() ); 294 295 #if( CONFIG_SCHED_DEBUG & 0x1 ) 296 if( hal_time_stamp() > CONFIG_SCHED_DEBUG ) sched_display( current->core->lid ); 297 #endif 283 298 284 299 // delay the yield if current thread has locks 285 if( thread_can_yield() == false)300 if( (current->local_locks != 0) || (current->remote_locks != 0) ) 286 301 { 287 302 current->flags |= THREAD_FLAG_SCHED; … … 289 304 } 290 305 291 // first loop on all threads to handle pending signals 292 sched_handle_signals( core ); 293 294 // second loop on threads to select next thread if required 295 if( next == NULL ) next = sched_select( core ); 306 // loop on threads to select next thread 307 next = sched_select( current->core ); 296 308 297 309 // check next thread attached to same core as the calling thread 298 assert( (next->core == current->core), __FUNCTION__ , "next core != current core\n"); 299 300 // check next thread not blocked 301 assert( (next->blocked == 0), __FUNCTION__ , "next thread is blocked\n"); 310 assert( (next->core == current->core), __FUNCTION__ , 311 "next core != current core\n"); 312 313 // check next thread not blocked when type != IDLE 314 assert( (next->blocked == 0) || (next->type = THREAD_IDLE) , __FUNCTION__ , 315 "next thread %x (%s) is blocked on core[%x,%d]\n", 316 next->trdid , thread_type_str(next->type) , local_cxy , current->core->lid ); 302 317 303 318 // switch contexts and update scheduler state if next != current 304 319 if( next != current ) 305 320 { 306 sched_dmsg("\n[DMSG] %s : trd %x (%s) on core[%x,%d] => trd %x (%s) / cycle %d\n", 307 __FUNCTION__, current->trdid, thread_type_str(current->type), local_cxy, core->lid, 308 next->trdid, thread_type_str(next->type), hal_time_stamp() ); 309 310 // calling thread desactivate IRQs 311 hal_disable_irq( &sr_save ); 321 // current thread desactivate IRQs 322 hal_disable_irq( &switch_save_sr[CURRENT_THREAD->core->lid] ); 323 324 sched_dmsg("\n[DBG] %s : core[%x,%d] / trd %x (%s) (%x,%x) => trd %x (%s) (%x,%x) / cycle %d\n", 325 __FUNCTION__, local_cxy, current->core->lid, 326 current, thread_type_str(current->type), current->process->pid, current->trdid, 327 next , thread_type_str(next->type) , next->process->pid , next->trdid, 328 hal_time_stamp() ); 312 329 313 330 // update scheduler 314 if( current->type == THREAD_USER ) sched->u_last = ¤t->sched_list; 315 else sched->k_last = ¤t->sched_list; 316 sched->current = next; 317 318 // handle FPU 331 sched_update( current , next ); 332 333 // handle FPU ownership 319 334 if( next->type == THREAD_USER ) 320 335 { 321 if( next == c ore->fpu_owner ) hal_fpu_enable();322 else hal_fpu_disable();336 if( next == current->core->fpu_owner ) hal_fpu_enable(); 337 else hal_fpu_disable(); 323 338 } 324 339 325 // switch contexts326 hal_ cpu_context_switch( current , next );327 328 // restore IRQs when callingthread resume329 hal_restore_irq( s r_save);340 // switch CPU from calling thread context to new thread context 341 hal_do_cpu_switch( current->cpu_context, next->cpu_context ); 342 343 // restore IRQs when next thread resume 344 hal_restore_irq( switch_save_sr[CURRENT_THREAD->core->lid] ); 330 345 } 331 346 else 332 347 { 333 sched_dmsg("\n[DMSG] %s : thread %x on core[%x,%d] continue / cycle %d\n", 334 __FUNCTION__, current->trdid, local_cxy, core->lid, hal_time_stamp() ); 348 349 sched_dmsg("\n[DBG] %s : core[%x,%d] / thread %x (%s) continue / cycle %d\n", 350 __FUNCTION__, local_cxy, current->core->lid, current->trdid, 351 thread_type_str(current->type) ,hal_time_stamp() ); 352 335 353 } 336 354 } // end sched_yield() 337 355 338 //////////////////// 339 void sched_display() 356 357 /////////////////////////////// 358 void sched_display( lid_t lid ) 340 359 { 341 360 list_entry_t * iter; … … 343 362 uint32_t save_sr; 344 363 345 thread_t * current = CURRENT_THREAD; 346 core_t * core = current->core; 364 if( lid >= LOCAL_CLUSTER->cores_nr ) 365 { 366 printk("\n[ERROR] in %s : illegal local index %d in cluster %x\n", 367 __FUNCTION__ , lid , local_cxy ); 368 return; 369 } 370 371 core_t * core = &LOCAL_CLUSTER->core_tbl[lid]; 347 372 scheduler_t * sched = &core->scheduler; 348 373 349 374 // get pointers on TXT0 chdev 350 xptr_t txt0_xp = chdev_dir.txt [0];375 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 351 376 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 352 377 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); … … 358 383 remote_spinlock_lock_busy( lock_xp , &save_sr ); 359 384 360 nolock_printk("\n***** scheduler state for core[%x,%d]\n" 361 "kernel_threads = %d / user_threads = %d / current = %x\n", 362 local_cxy , core->lid, 363 sched->k_threads_nr, sched->u_threads_nr, sched->current->trdid ); 385 nolock_printk("\n***** scheduler state for core[%x,%d] at cycle %d\n" 386 "kernel_threads = %d / user_threads = %d / current = %x / idle = %x\n", 387 local_cxy , core->lid, hal_time_stamp(), 388 sched->k_threads_nr, sched->u_threads_nr, 389 sched->current->trdid , sched->idle->trdid ); 364 390 365 391 // display kernel threads … … 367 393 { 368 394 thread = LIST_ELEMENT( iter , thread_t , sched_list ); 369 nolock_printk(" - type = %s / trdid = % x / pid = %x / func = %x / blocked_vect = %x\n",395 nolock_printk(" - type = %s / trdid = %X / pid = %X / func = %X / blocked = %X\n", 370 396 thread_type_str( thread->type ), thread->trdid, thread->process->pid, 371 397 thread->entry_func, thread->blocked ); … … 376 402 { 377 403 thread = LIST_ELEMENT( iter , thread_t , sched_list ); 378 nolock_printk(" - type = %s / trdid = % x / pid = %x / func = %x / blocked_vect = %x\n",404 nolock_printk(" - type = %s / trdid = %X / pid = %X / func = %X / blocked = %X\n", 379 405 thread_type_str( thread->type ), thread->trdid, thread->process->pid, 380 406 thread->entry_func, thread->blocked ); -
trunk/kernel/kern/scheduler.h
r296 r407 74 74 75 75 /********************************************************************************************* 76 * This function handles pending signals for all registered threads, and tries to make 77 * a context switch for the core running the calling thread. 78 * - If the <next> argument is not NULL, this next thread starts execution. 79 * - If <next> is NULL, it calls the sched_select() function. If there is a runable thread 80 * (other than current thread or idle thread), this selected thread starts execution. 81 * - If there is no other runable thread, the calling thread continues execution. 82 * - If there is no runable thread, the idle thread is executed. 83 ********************************************************************************************* 84 * @ next : local pointer on next thread to run / call sched_select() if NULL. 76 * This function handles pending signals for all registered threads, and calls the 77 * sched_select() function to make a context switch for the core running the calling thread. 85 78 ********************************************************************************************/ 86 void sched_yield( struct thread_s * next);79 void sched_yield(); 87 80 88 81 /********************************************************************************************* … … 96 89 /********************************************************************************************* 97 90 * This function is used by the scheduler of a given core to actually kill a thread that has 98 * the SIG_KILL signal set (following a thread_exit() or a thread_kill() event).91 * the SIG_KILL / SIG_SUICIDE signal set (following a thread_exit() or a thread_kill() event). 99 92 * - It checks that the thread has released all locks => panic otherwise... 100 * - It detach the thread from the local process descriptor.101 93 * - It removes the thread from the scheduler. 102 * - It release physical memory allocated for thread descriptor. 94 * - It reset the SIG_KILL signal to acknoledge the killer. 95 * - In case of SIG_SUCIDE, it removes the detached thread from its process, and destroys it. 103 96 ********************************************************************************************* 104 97 * @ thread : local pointer on the thread descriptor. … … 121 114 122 115 /********************************************************************************************* 123 * This function display the internal state of the calling core scheduler. 116 * This function display the internal state of the local core identified by its <lid>. 117 ********************************************************************************************* 118 * @ lid : local index of target core. 124 119 ********************************************************************************************/ 125 void sched_display( );120 void sched_display( lid_t lid ); 126 121 127 122 -
trunk/kernel/kern/signal.c
r406 r407 44 44 hal_atomic_or( &thread->signals , (1 << sig_id) ); 45 45 46 signal_dmsg("\n[D MSG] %s : thread %x in process %x received signal %d\n",46 signal_dmsg("\n[DBG] %s : thread %x in process %x received signal %d\n", 47 47 __FUNCTION__, thread->trdid , process->pid , sig_id ); 48 48 } … … 59 59 thread_s * this = CURRENT_THREAD; 60 60 61 printk("\n[D MSG] %s : threadReceived signal %d, pid %d, tid %x, core %d [ KILLED ]\n",61 printk("\n[DBG] %s : threadReceived signal %d, pid %d, tid %x, core %d [ KILLED ]\n", 62 62 sig, 63 63 this->process->pid, -
trunk/kernel/kern/thread.c
r406 r407 57 57 else if( type == THREAD_RPC ) return "RPC"; 58 58 else if( type == THREAD_DEV ) return "DEV"; 59 else if( type == THREAD_KERNEL ) return "KER";60 59 else if( type == THREAD_IDLE ) return "IDL"; 61 60 else return "undefined"; … … 153 152 } 154 153 154 // compute thread descriptor size without kernel stack 155 uint32_t desc_size = (intptr_t)(&thread->signature) - (intptr_t)thread + 4; 156 155 157 // Initialize new thread descriptor 156 158 thread->trdid = trdid; … … 170 172 thread->u_stack_base = u_stack_base; 171 173 thread->u_stack_size = u_stack_size; 172 thread->k_stack_base = (intptr_t)thread ;173 thread->k_stack_size = CONFIG_THREAD_DESC_SIZE ;174 thread->k_stack_base = (intptr_t)thread + desc_size; 175 thread->k_stack_size = CONFIG_THREAD_DESC_SIZE - desc_size; 174 176 175 177 thread->entry_func = func; // thread entry point … … 178 180 thread->signals = 0; // no pending signal 179 181 thread->errno = 0; // no error detected 180 thread->fork_user = 0; // no fork required181 thread->fork_cxy = 0; 182 thread->fork_user = 0; // no user defined placement for fork 183 thread->fork_cxy = 0; // user defined target cluster for fork 182 184 183 185 // thread blocked … … 221 223 vseg_t * vseg; // stack vseg 222 224 223 thread_dmsg("\n[DMSG] %s : enters for process %x\n", __FUNCTION__ , pid);225 assert( (attr != NULL) , __FUNCTION__, "pthread attributes must be defined" ); 224 226 225 227 // get process descriptor local copy … … 234 236 235 237 // select a target core in local cluster 236 if( attr->attributes & PT_ATTR_CORE_DEFINED ) core_lid = attr->lid; 237 else core_lid = cluster_select_local_core(); 238 239 // check core local index 240 if( core_lid >= LOCAL_CLUSTER->cores_nr ) 241 { 242 printk("\n[ERROR] in %s : illegal core index attribute = %d\n", 243 __FUNCTION__ , core_lid ); 244 245 return EINVAL; 238 if( attr->attributes & PT_ATTR_CORE_DEFINED ) 239 { 240 core_lid = attr->lid; 241 if( core_lid >= LOCAL_CLUSTER->cores_nr ) 242 { 243 printk("\n[ERROR] in %s : illegal core index attribute = %d\n", 244 __FUNCTION__ , core_lid ); 245 return EINVAL; 246 } 247 } 248 else 249 { 250 core_lid = cluster_select_local_core(); 246 251 } 247 252 248 253 // allocate a stack from local VMM 249 vseg = vmm_create_vseg( process, 0 , 0 , VSEG_TYPE_STACK ); 254 vseg = vmm_create_vseg( process, 255 VSEG_TYPE_STACK, 256 0, // size unused 257 0, // length unused 258 0, // file_offset unused 259 0, // file_size unused 260 XPTR_NULL, // mapper_xp unused 261 local_cxy ); 250 262 251 263 if( vseg == NULL ) … … 287 299 288 300 // set DETACHED flag if required 289 if( attr->attributes & PT_ATTR_DETACH ) thread->flags |= THREAD_FLAG_DETACHED; 301 if( attr->attributes & PT_ATTR_DETACH ) 302 { 303 thread->flags |= THREAD_FLAG_DETACHED; 304 } 290 305 291 306 // allocate & initialize CPU context 292 error = hal_cpu_context_create( thread ); 293 294 if( error ) 307 if( hal_cpu_context_create( thread ) ) 295 308 { 296 309 printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ ); … … 300 313 } 301 314 302 // allocate & initialize FPU context 303 error = hal_fpu_context_create( thread ); 304 305 if( error ) 315 // allocate FPU context 316 if( hal_fpu_context_alloc( thread ) ) 306 317 { 307 318 printk("\n[ERROR] in %s : cannot create FPU context\n", __FUNCTION__ ); … … 311 322 } 312 323 313 thread_dmsg("\n[DMSG] %s : exit / trdid = %x / process %x / core = %d\n", 314 __FUNCTION__ , thread->trdid , process->pid , core_lid ); 324 thread_dmsg("\n[DBG] %s : core[%x,%d] exit / trdid = %x / process %x / core = %d\n", 325 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, 326 thread->trdid , process->pid , core_lid ); 315 327 316 328 *new_thread = thread; … … 319 331 } // end thread_user_create() 320 332 321 ////////////////////////////////////////////// 333 //////////////////////////////////////////////////// 322 334 error_t thread_user_fork( process_t * process, 335 intptr_t stack_base, 336 uint32_t stack_size, 323 337 thread_t ** new_thread ) 324 338 { 325 339 error_t error; 326 thread_t * thread; // pointer on new thread descriptor340 thread_t * child; // pointer on new thread descriptor 327 341 lid_t core_lid; // selected core local index 328 vseg_t * vseg; // stack vseg 329 330 thread_dmsg("\n[DMSG] %s : enters\n", __FUNCTION__ ); 331 332 // allocate a stack from local VMM 333 vseg = vmm_create_vseg( process, 0 , 0 , VSEG_TYPE_STACK ); 334 335 if( vseg == NULL ) 336 { 337 printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ ); 338 return ENOMEM; 339 } 342 343 thread_dmsg("\n[DBG] %s : core[%x,%d] enters\n", 344 __FUNCTION__ , local_cxy , core_lid ); 340 345 341 346 // select a target core in local cluster 342 347 core_lid = cluster_select_local_core(); 343 348 344 // get pointer on callingthread descriptor345 thread_t * this= CURRENT_THREAD;349 // get pointer on parent thread descriptor 350 thread_t * parent = CURRENT_THREAD; 346 351 347 352 // allocate memory for new thread descriptor 348 thread = thread_alloc();349 350 if( thread == NULL )353 child = thread_alloc(); 354 355 if( child == NULL ) 351 356 { 352 357 printk("\n[ERROR] in %s : cannot allocate new thread\n", __FUNCTION__ ); 353 vmm_remove_vseg( vseg );354 358 return ENOMEM; 355 359 } 356 360 357 361 // initialize thread descriptor 358 error = thread_init( thread,362 error = thread_init( child, 359 363 process, 360 364 THREAD_USER, 361 this->entry_func,362 this->entry_args,365 parent->entry_func, 366 parent->entry_args, 363 367 core_lid, 364 vseg->min,365 vseg->max - vseg->min);368 stack_base, 369 stack_size ); 366 370 367 371 if( error ) 368 372 { 369 373 printk("\n[ERROR] in %s : cannot initialize new thread\n", __FUNCTION__ ); 370 vmm_remove_vseg( vseg ); 371 thread_release( thread ); 374 thread_release( child ); 372 375 return EINVAL; 373 376 } 374 377 375 // set ATTACHED flag if set in this thread376 if( this->flags & THREAD_FLAG_DETACHED ) thread->flags = THREAD_FLAG_DETACHED;377 378 // allocate & initialize CPU context from calling thread379 error = hal_cpu_context_copy( thread , this );380 381 if( error )382 { 383 printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ ); 384 vmm_remove_vseg( vseg);385 thread_release( thread );378 // return child pointer 379 *new_thread = child; 380 381 // set DETACHED flag if required 382 if( parent->flags & THREAD_FLAG_DETACHED ) child->flags = THREAD_FLAG_DETACHED; 383 384 // allocate CPU context for child thread 385 if( hal_cpu_context_alloc( child ) ) 386 { 387 printk("\n[ERROR] in %s : cannot allocate CPU context\n", __FUNCTION__ ); 388 thread_release( child ); 386 389 return ENOMEM; 387 390 } 388 391 389 // allocate & initialize FPU context from calling thread 390 error = hal_fpu_context_copy( thread , this ); 391 392 if( error ) 393 { 394 printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ ); 395 vmm_remove_vseg( vseg ); 396 thread_release( thread ); 392 // allocate FPU context for child thread 393 if( hal_fpu_context_alloc( child ) ) 394 { 395 printk("\n[ERROR] in %s : cannot allocate FPU context\n", __FUNCTION__ ); 396 thread_release( child ); 397 397 return ENOMEM; 398 398 } 399 399 400 thread_dmsg("\n[DMSG] %s : exit / thread %x for process %x on core %d in cluster %x\n", 401 __FUNCTION__, thread->trdid, process->pid, core_lid, local_cxy ); 402 403 *new_thread = thread; 400 // copy kernel stack content from parent to child thread descriptor 401 void * dst = (void *)(&child->signature) + 4; 402 void * src = (void *)(&parent->signature) + 4; 403 memcpy( dst , src , parent->k_stack_size ); 404 405 thread_dmsg("\n[DBG] %s : core[%x,%d] exit / created main thread %x for process %x\n", 406 __FUNCTION__, local_cxy , core_lid , child->trdid , process->pid ); 407 404 408 return 0; 405 409 … … 416 420 thread_t * thread; // pointer on new thread descriptor 417 421 418 thread_dmsg("\n[DMSG] %s : enter / for type %s on core[%x,%d] / cycle %d\n", 419 __FUNCTION__ , thread_type_str( type ) , local_cxy , core_lid , hal_time_stamp() ); 420 421 assert( ( (type == THREAD_KERNEL) || (type == THREAD_RPC) || 422 (type == THREAD_IDLE) || (type == THREAD_DEV) ) , 423 __FUNCTION__ , "illegal thread type" ); 422 thread_dmsg("\n[DBG] %s : core[%x,%d] enters / type % / cycle %d\n", 423 __FUNCTION__ , local_cxy , core_lid , thread_type_str( type ) , hal_time_stamp() ); 424 425 assert( ( (type == THREAD_IDLE) || (type == THREAD_RPC) || (type == THREAD_DEV) ) , 426 __FUNCTION__ , "illegal thread type" ); 424 427 425 428 assert( (core_lid < LOCAL_CLUSTER->cores_nr) , … … 449 452 hal_cpu_context_create( thread ); 450 453 451 thread_dmsg("\n[DMSG] %s : exit / trdid = %x / type = %s / core = [%x,%d] / cycle %d\n", 452 __FUNCTION__ , thread->trdid , thread_type_str(type) , 453 local_cxy , core_lid , hal_time_stamp() ); 454 thread_dmsg("\n[DBG] %s : core = [%x,%d] exit / trdid = %x / type %s / cycle %d\n", 455 __FUNCTION__, local_cxy, core_lid, thread->trdid, thread_type_str(type), hal_time_stamp() ); 454 456 455 457 *new_thread = thread; … … 465 467 lid_t core_lid ) 466 468 { 467 assert( ( (type == THREAD_KERNEL) || (type == THREAD_RPC) || 468 (type == THREAD_IDLE) || (type == THREAD_DEV) ) , 469 __FUNCTION__ , "illegal thread type" ); 470 471 if( core_lid >= LOCAL_CLUSTER->cores_nr ) 472 { 473 panic("illegal core_lid / cores = %d / lid = %d / cxy = %x", 474 LOCAL_CLUSTER->cores_nr , core_lid , local_cxy ); 475 } 469 assert( (type == THREAD_IDLE) , __FUNCTION__ , "illegal thread type" ); 470 471 assert( (core_lid < LOCAL_CLUSTER->cores_nr) , __FUNCTION__ , "illegal core index" ); 476 472 477 473 error_t error = thread_init( thread, … … 487 483 488 484 return error; 489 } 485 486 } // end thread_kernel_init() 490 487 491 488 /////////////////////////////////////////////////////////////////////////////////////// … … 502 499 core_t * core = thread->core; 503 500 504 thread_dmsg("\n[D MSG] %s : enters for thread %x in process %x / type = %s\n",501 thread_dmsg("\n[DBG] %s : enters for thread %x in process %x / type = %s\n", 505 502 __FUNCTION__ , thread->trdid , process->pid , thread_type_str( thread->type ) ); 506 503 … … 556 553 tm_end = hal_get_cycles(); 557 554 558 thread_dmsg("\n[D MSG] %s : exit for thread %x in process %x / duration = %d\n",555 thread_dmsg("\n[DBG] %s : exit for thread %x in process %x / duration = %d\n", 559 556 __FUNCTION__, thread->trdid , process->pid , tm_end - tm_start ); 560 } 557 558 } // end thread_destroy() 561 559 562 560 ///////////////////////////////////////////////// … … 609 607 { 610 608 hal_atomic_or( &thread->signals , mask ); 609 hal_fence(); 611 610 } 612 611 … … 616 615 { 617 616 hal_atomic_and( &thread->signals , ~mask ); 618 } 619 620 ////////////////////////////////// 621 inline bool_t thread_is_joinable() 622 { 623 thread_t * this = CURRENT_THREAD; 624 return( (this->brothers_list.next != XPTR_NULL) && 625 (this->brothers_list.pred != XPTR_NULL) ); 626 } 627 628 ////////////////////////////////// 629 inline bool_t thread_is_runnable() 630 { 631 thread_t * this = CURRENT_THREAD; 632 return( this->blocked == 0 ); 617 hal_fence(); 633 618 } 634 619 … … 650 635 { 651 636 this->flags &= ~THREAD_FLAG_SCHED; 652 sched_yield( NULL ); 653 } 654 } 637 sched_yield(); 638 } 639 640 } // end thread_check_sched() 641 642 ///////////////////////////////////// 643 void thread_block( thread_t * thread, 644 uint32_t cause ) 645 { 646 // set blocking cause 647 hal_atomic_or( &thread->blocked , cause ); 648 hal_fence(); 649 650 } // end thread_block() 651 652 ///////////////////////////////////////// 653 uint32_t thread_unblock( xptr_t thread, 654 uint32_t cause ) 655 { 656 // get thread cluster and local pointer 657 cxy_t cxy = GET_CXY( thread ); 658 thread_t * ptr = (thread_t *)GET_PTR( thread ); 659 660 // reset blocking cause 661 uint32_t previous = hal_remote_atomic_and( XPTR( cxy , &ptr->blocked ) , ~cause ); 662 hal_fence(); 663 664 // return a non zero value if the cause bit is modified 665 return( previous & cause ); 666 667 } // end thread_unblock() 655 668 656 669 ///////////////////// … … 664 677 if( !thread_can_yield() ) 665 678 { 666 printk("ERROR in %s : thread %x in process %x on core %d in cluster %x\n" 667 " did not released all locks\n", 668 __FUNCTION__ , this->trdid , this->process->pid , 669 CURRENT_CORE->lid , local_cxy ); 679 printk("ERROR in %s : locks not released for thread %x in process %x on core[%x,%d]\n", 680 __FUNCTION__, this->trdid, this->process->pid, local_cxy, this->core->lid ); 670 681 return EINVAL; 671 682 } … … 686 697 687 698 // deschedule 688 sched_yield( NULL);699 sched_yield(); 689 700 return 0; 690 } 691 692 ///////////////////////////////////// 693 void thread_block( thread_t * thread, 694 uint32_t cause ) 695 { 696 // set blocking cause 697 hal_atomic_or( &thread->blocked , cause ); 698 } 699 700 //////////////////////////////////// 701 void thread_unblock( xptr_t thread, 702 uint32_t cause ) 703 { 704 // get thread cluster and local pointer 705 cxy_t cxy = GET_CXY( thread ); 706 thread_t * ptr = (thread_t *)GET_PTR( thread ); 707 708 // reset blocking cause 709 hal_remote_atomic_and( XPTR( cxy , &ptr->blocked ) , ~cause ); 710 } 701 702 } // end thread_exit() 711 703 712 704 ///////////////////////////////////// … … 721 713 // send an IPI to schedule the target thread core. 722 714 dev_pic_send_ipi( local_cxy , target->core->lid ); 723 } 715 716 } // end thread_kill() 724 717 725 718 /////////////////////// 726 719 void thread_idle_func() 727 720 { 728 #if CONFIG_IDLE_DEBUG729 lid_t lid = CURRENT_CORE->lid;730 #endif731 732 721 while( 1 ) 733 722 { 734 idle_dmsg("\n[DMSG] %s : core[%x][%d] goes to sleep at cycle %d\n", 735 __FUNCTION__ , local_cxy , lid , hal_get_cycles() ); 736 737 // force core to sleeping state 738 //hal_core_sleep(); 739 740 idle_dmsg("\n[DMSG] %s : core[%x][%d] wake up at cycle %d\n", 741 __FUNCTION__ , local_cxy , lid , hal_get_cycles() ); 742 743 // force scheduling 744 sched_yield( NULL ); 723 if( CONFIG_THREAD_IDLE_MODE_SLEEP ) // force core to low-power mode 724 { 725 726 idle_dmsg("\n[DBG] %s : core[%x][%d] goes to sleep at cycle %d\n", 727 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_get_cycles() ); 728 729 hal_core_sleep(); 730 731 idle_dmsg("\n[DBG] %s : core[%x][%d] wake up at cycle %d\n", 732 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_get_cycles() ); 733 734 } 735 else // yield each ~ 100000 cycles 736 737 { 738 hal_fixed_delay( 500000 ); 739 } 740 741 // force scheduling at each iteration 742 sched_yield(); 745 743 } 746 } 744 } // end thread_idle() 745 747 746 748 747 ///////////////////////////////////////////////// -
trunk/kernel/kern/thread.h
r406 r407 27 27 28 28 #include <hal_types.h> 29 #include <shared_syscalls.h> 29 30 #include <hal_special.h> 30 31 #include <xlist.h> … … 51 52 52 53 /*************************************************************************************** 53 * This defines the various pthread_attr_t attributes bit-vector.54 **************************************************************************************/55 56 /***************************************************************************************57 * This opaque structure contains the user defined attributes for a user thread.58 * It is passed as input argument to the thread_user_create() function.59 * It is set by the user application itself, using the pthread_attr_***() functions.60 * The currently supported attributes are defined below.61 **************************************************************************************/62 63 typedef struct pthread_attr_s64 {65 uint32_t attributes; /*! user defined attributes bit vector */66 cxy_t cxy; /*! target cluster identifier */67 lid_t lid; /*! target core index */68 }69 pthread_attr_t;70 71 typedef enum72 {73 PT_ATTR_DETACH = 0x0001, /*! user defined not joinable */74 PT_ATTR_CLUSTER_DEFINED = 0x0002, /*! user defined target cluster */75 PT_ATTR_CORE_DEFINED = 0x0004, /*! user defined core index in cluster */76 }77 pt_attributes_t;78 79 /***************************************************************************************80 54 * This enum defines the thread types. 81 55 **************************************************************************************/ … … 86 60 THREAD_RPC = 1, /*! kernel thread executing pending RPCs */ 87 61 THREAD_DEV = 2, /*! kernel thread executing I/O device commands */ 88 THREAD_KERNEL = 3, /*! other kernel thread */ 89 THREAD_IDLE = 4, /*! kernel idle thread */ 90 THREAD_TYPES_NR 62 THREAD_IDLE = 3, /*! kernel idle thread */ 91 63 } 92 64 thread_type_t; … … 100 72 #define THREAD_FLAG_JOIN 0x0004 /*! Parent thread made a join */ 101 73 #define THREAD_FLAG_EXIT 0x0008 /*! This thread made an exit */ 102 #define THREAD_FLAG_SCHED 0x0010 /*! Descheduling required for this thread*/74 #define THREAD_FLAG_SCHED 0x0010 /*! Scheduling required for this thread */ 103 75 104 76 /*************************************************************************************** … … 106 78 **************************************************************************************/ 107 79 108 #define THREAD_SIG_KILL 0x0001 /*! This thread must be destroyed ASAP */ 80 #define THREAD_SIG_KILL 0x0001 /*! This thread killed by another thread */ 81 #define THREAD_SIG_SUICIDE 0x0002 /*! This thread required exit */ 109 82 110 83 /*************************************************************************************** … … 116 89 #define THREAD_BLOCKED_MAPPER 0x0004 /*! thread wait mapper */ 117 90 #define THREAD_BLOCKED_JOIN 0x0008 /*! thread blocked in join / wait exit */ 118 #define THREAD_BLOCKED_EXIT 0x0010 /*! thread blocked in exit / wait join i*/91 #define THREAD_BLOCKED_EXIT 0x0010 /*! thread blocked in exit / wait join */ 119 92 #define THREAD_BLOCKED_KILL 0x0020 /*! thread received kill signal */ 120 93 #define THREAD_BLOCKED_SEM 0x0040 /*! thread wait semaphore */ 121 94 #define THREAD_BLOCKED_PAGE 0x0080 /*! thread wait page access */ 122 95 #define THREAD_BLOCKED_USERSYNC 0x0100 /*! thread wait POSIX (cond/mutex/barrier) */ 123 124 #define THREAD_BLOCKED_IDLE 0x1000 /*! thread RPC wait activation */ 96 #define THREAD_BLOCKED_RPC 0x0200 /*! thread wait RPC completion */ 97 125 98 #define THREAD_BLOCKED_DEV_QUEUE 0x2000 /*! thread DEV wait queue */ 126 99 #define THREAD_BLOCKED_DEV_ISR 0x4000 /*! thread DEV wait ISR */ … … 199 172 200 173 uint32_t flags; /*! bit vector of flags */ 201 uint32_tblocked; /*! bit vector of blocking causes */202 uint32_t signals; /*! bit vector of signals*/174 volatile uint32_t blocked; /*! bit vector of blocking causes */ 175 volatile uint32_t signals; /*! bit vector of (KILL / SUICIDE) signals */ 203 176 204 177 error_t errno; /*! errno value set by last system call */ … … 212 185 remote_spinlock_t * children_lock; /*! lock protecting the children list */ 213 186 214 xlist_entry_t brothers_list; /*! member of threads with same parent*/187 xlist_entry_t brothers_list; /*! list of attached threads to same parent */ 215 188 216 189 list_entry_t sched_list; /*! member of threads attached to same core */ … … 273 246 274 247 /*************************************************************************************** 275 * This function allocates memory for an user thread descriptor in the local cluster, 248 * This function is used by the fork() system call to create the child process main 249 * thread. It allocates memory for an user thread descriptor in the local cluster, 276 250 * and initializes it from information contained in the calling thread descriptor. 277 * It is used by the fork() system call to create the child process main thread. 278 * The new thread is attached to the core with the lowest load. 279 * It is registered in the process descriptor defined by the "process" argument. 280 * This new thread inherits its execution context from the calling thread, 281 * and the "loadable" field is NOT set. 282 * The THREAD_BLOCKED_GLOBAL bit is set, and the thread must be activated to start. 251 * The new thread is attached to the core that has the lowest load in local cluster. 252 * It is registered in the child process descriptor defined by the <process> argument. 253 * This new thread inherits its user stack from the parent thread, as it uses the 254 * Copy-On-Write mechanism to get a private stack when required. 255 * The content of the parent kernel stack is copied into the child kernel stack, as 256 * the Copy-On-Write mechanism cannot be used for kernel segments (because kernel 257 * uses physical addressing on some architectures). 258 * The CPU and FPU execution contexts are created and linked to the new thread, 259 * but the actual context copy is NOT done. The THREAD_BLOCKED_GLOBAL bit is set, 260 * and the thread must be explicitely unblocked later to make the new thread runable. 283 261 *************************************************************************************** 284 262 * @ process : local pointer on owner process descriptor. 263 * @ stack_base : user stack base address (from parent). 264 * @ stack_size : user stack size (from parent). 285 265 * @ new_thread : [out] address of buffer for new thread descriptor pointer. 286 266 * @ returns 0 if success / returns ENOMEM if error. 287 267 **************************************************************************************/ 288 268 error_t thread_user_fork( process_t * process, 269 intptr_t stack_base, 270 uint32_t stack_size, 289 271 thread_t ** new_thread ); 290 272 … … 351 333 * It does NOT take a lock, as this function is always called by the parent thread. 352 334 *************************************************************************************** 353 * @ xp_parent: extended pointer on the parent thread descriptor.354 * @ xp_child: extended pointer on the child thread descriptor.355 **************************************************************************************/ 356 void thread_child_parent_link( xptr_t xp_parent,357 xptr_t xp_child);335 * @ parent_xp : extended pointer on the parent thread descriptor. 336 * @ child_xp : extended pointer on the child thread descriptor. 337 **************************************************************************************/ 338 void thread_child_parent_link( xptr_t parent_xp, 339 xptr_t child_xp ); 358 340 359 341 /*************************************************************************************** … … 361 343 * of attached children threads. 362 344 *************************************************************************************** 363 * @ xp_parent: extended pointer on the parent thread descriptor.364 * @ xp_child: extended pointer on the child thread descriptor.365 **************************************************************************************/ 366 void thread_child_parent_unlink( xptr_t xp_parent,367 xptr_t xp_child);345 * @ parent_xp : extended pointer on the parent thread descriptor. 346 * @ child_xp : extended pointer on the child thread descriptor. 347 **************************************************************************************/ 348 void thread_child_parent_unlink( xptr_t parent_xp, 349 xptr_t child_xp ); 368 350 369 351 /*************************************************************************************** … … 386 368 387 369 /*************************************************************************************** 388 * This function returns true if the calling thread is attached to its parent thread.389 **************************************************************************************/390 inline bool_t thread_is_joinable();391 392 /***************************************************************************************393 * This function returns true if the calling thread is not blocked.394 **************************************************************************************/395 inline bool_t thread_is_runnable();396 397 /***************************************************************************************398 370 * This function checks if the calling thread can deschedule. 399 371 *************************************************************************************** … … 403 375 404 376 /*************************************************************************************** 405 * This function implements the delayed descheduling m achanism : It is called by377 * This function implements the delayed descheduling mechanism : It is called by 406 378 * all lock release functions, and calls the sched_yield() function when all locks 407 * have beeen released and the THREAD_FLAG_SCHED flag is set.379 * have beeen released and the calling thread THREAD_FLAG_SCHED flag is set. 408 380 **************************************************************************************/ 409 381 void thread_check_sched(); 410 382 411 383 /*************************************************************************************** 412 * This function can be used by the calling thread to suicide. 413 * All locks must be previously released. 414 * The scenario depends on the attached/detached flag : 415 * - if detached, it sets the SIG_KILL signal in the "signals" bit_vector, registers 416 * the BLOCKED_EXIT bit in the "blocked" bit_vector, and deschedule. 417 * - if attached, it simply sets the BLOCKED_EXIT bit in the "blocked" bit vector 418 * and deschedule. The SIG_KILL signal will be set by the parent thread when 419 * executing the pthread_join(). 384 * This function is used by the calling thread to suicide. 385 * All locks must be previously released. The scenario depends on the DETACHED flag. 386 * if detached : 387 * 1) the calling thread sets the SIG_SUICIDE bit in the "signals" bit_vector, 388 * registers the BLOCKED_GLOBAL bit in the "blocked" bit_vector, and deschedule. 389 * 2) the scheduler, detecting the SIG_SUICIDE bit, remove the thread from the 390 * scheduler list, remove the thread from its process, and destroys the thread. 391 * if attached : 392 * 1) the calling thread simply sets the BLOCKED_EXIT bit in the "blocked" bit vector 393 * and deschedule. 394 * 2) The SIG_KILL bit and BLOCKED_SIGNAL bits are set by the parent thread when 395 * executing the pthread_join(), and detecting the BLOCKED_EXIT bit. 396 * The scenario is a standard kill as described below. 420 397 *************************************************************************************** 421 398 * @ returns 0 if success / returns EINVAL if locks_count is not zero. … … 424 401 425 402 /*************************************************************************************** 403 * This function request to kill a local target thread, with the following scenario: 404 * 1. This function set the BLOCKED_GLOBAL bit in target thread "blocked" bit_vector, 405 * set the SIG_KILL bit in target thread "signals" bit_vector, and send an IPI 406 * to the target thread core to force scheduling. 407 * 2. The scheduler, detecting the SIG_KILL set, removes the thread from the scheduler 408 * list, and reset the SIG_KILL bit to acknowledge the killer. 409 * 3. The caller of this function, (such as the process_kill() function), must poll 410 * SIG_KILL bit until reset, detach the thread from its parent if the thread is 411 * attached, remove the thread from its process, and destroys the thread. 412 * 413 * NOTE: The third step must be done by the caller to allows the process_kill() 414 * function to parallelize the work on all schedulers in a given cluster. 415 *************************************************************************************** 416 * @ thread : local pointer on the target thread. 417 **************************************************************************************/ 418 void thread_kill( thread_t * thread ); 419 420 /*************************************************************************************** 426 421 * This function registers a blocking cause in the target thread "blocked" bit vector. 427 * Warning : this function does not deschedule the calling thread .428 * The descheduling can beforced by a sched_yield().429 *************************************************************************************** 430 * @ thread : local pointer on target thread .422 * Warning : this function does not deschedule the calling thread, and the descheduling 423 * must be explicitely forced by a sched_yield(). 424 *************************************************************************************** 425 * @ thread : local pointer on target thread descriptor. 431 426 * @ cause : mask defining the cause (one hot). 432 427 **************************************************************************************/ … … 436 431 /*************************************************************************************** 437 432 * This function resets the bit identified by the cause argument in the "blocked" 438 * bit vector of a remote thread descriptor .433 * bit vector of a remote thread descriptor, using an atomic access. 439 434 * We need an extended pointer, because the client thread of an I/O operation on a 440 435 * given device is not in the same cluster as the associated device descriptor. … … 444 439 * @ thread : extended pointer on the remote thread. 445 440 * @ cause : mask defining the cause (one hot). 446 **************************************************************************************/ 447 void thread_unblock( xptr_t thread, 448 uint32_t cause ); 449 450 /*************************************************************************************** 451 * This function kills a target thread, identified by its local pointer. 452 * It is generally called by the local process_destroy() function. 453 * - it forces the global blocked bit in target thread descriptor. 454 * - it set the SIG_KILL signal in target thread. 455 * - it send an IPI_SCHED_REQUEST to the target thread core. 456 *************************************************************************************** 457 * @ thread : local pointer on the target thread. 458 * @ returns 0 if success / returns EINVAL if locks_count is not zero. 459 **************************************************************************************/ 460 void thread_kill( thread_t * thread ); 441 * @ return non zero if the bit-vector was actually modified / return 0 otherwise 442 **************************************************************************************/ 443 uint32_t thread_unblock( xptr_t thread, 444 uint32_t cause ); 461 445 462 446 /*************************************************************************************** -
trunk/kernel/libk/elf.c
r406 r407 175 175 } 176 176 177 // get .elf file descriptor cluster and local pointer 178 cxy_t file_cxy = GET_CXY( file_xp ); 179 vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp ); 180 181 // get local pointer on .elf file mapper 182 mapper_t * mapper_ptr = (mapper_t *)hal_remote_lpt( XPTR( file_cxy , 183 &file_ptr->mapper ) ); 177 184 // register vseg in VMM 178 185 vseg = (vseg_t *)vmm_create_vseg( process, 186 type, 179 187 vbase, 180 188 mem_size, 181 type ); 189 file_offset, 190 file_size, 191 XPTR( file_cxy , mapper_ptr ), 192 local_cxy ); 182 193 if( vseg == NULL ) 183 194 { … … 187 198 } 188 199 189 // get .elf file descriptor cluster and local pointer190 cxy_t file_cxy = GET_CXY( file_xp );191 vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );192 193 // get local pointer on .elf file mapper194 mapper_t * mapper_ptr = (mapper_t *)hal_remote_lpt( XPTR( file_cxy ,195 &file_ptr->mapper ) );196 197 // initialize "file_mapper", "file_offset", "file_size" fields in vseg198 vseg->mapper_xp = XPTR( file_cxy , mapper_ptr );199 vseg->file_offset = file_offset;200 vseg->file_size = file_size;201 202 200 // update reference counter in file descriptor 203 201 vfs_file_count_up( file_xp ); 204 202 205 elf_dmsg("\n[D MSG] %s : found %s vseg / base = %x / size = %x\n"203 elf_dmsg("\n[DBG] %s : found %s vseg / base = %x / size = %x\n" 206 204 " file_size = %x / file_offset = %x / mapper_xp = %l\n", 207 205 __FUNCTION__ , vseg_type_str(vseg->type) , vseg->min , vseg->max - vseg->min , … … 225 223 error_t error; 226 224 227 elf_dmsg("\n[D MSG] %s : core[%x,%d] enter for <%s>\n",225 elf_dmsg("\n[DBG] %s : core[%x,%d] enter for <%s>\n", 228 226 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pathname ); 229 227 … … 233 231 234 232 // open file 235 error = vfs_open( process ->vfs_cwd_xp,233 error = vfs_open( process, 236 234 pathname, 237 235 O_RDONLY, … … 245 243 } 246 244 247 elf_dmsg("\n[D MSG] %s : open file <%s>\n", __FUNCTION__ , pathname );245 elf_dmsg("\n[DBG] %s : open file <%s>\n", __FUNCTION__ , pathname ); 248 246 249 247 // load header in local buffer … … 258 256 } 259 257 260 elf_dmsg("\n[D MSG] %s : loaded elf header for %s\n", __FUNCTION__ , pathname );258 elf_dmsg("\n[DBG] %s : loaded elf header for %s\n", __FUNCTION__ , pathname ); 261 259 262 260 if( header.e_phnum == 0 ) … … 295 293 } 296 294 297 elf_dmsg("\n[D MSG] %s : segments array allocated for %s\n", __FUNCTION__ , pathname );295 elf_dmsg("\n[DBG] %s : segments array allocated for %s\n", __FUNCTION__ , pathname ); 298 296 299 297 // load seg descriptors array to local buffer … … 312 310 } 313 311 314 elf_dmsg("\n[D MSG] %s loaded segments descriptors for %s \n", __FUNCTION__ , pathname );312 elf_dmsg("\n[DBG] %s loaded segments descriptors for %s \n", __FUNCTION__ , pathname ); 315 313 316 314 // register loadable segments in process VMM … … 337 335 kmem_free(&req); 338 336 339 elf_dmsg("\n[D MSG] %s : core[%x,%d] exit for <%s> / entry_point = %x\n",337 elf_dmsg("\n[DBG] %s : core[%x,%d] exit for <%s> / entry_point = %x\n", 340 338 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , pathname , header.e_entry ); 341 339 -
trunk/kernel/libk/remote_barrier.c
r296 r407 274 274 // block & deschedule the calling thread 275 275 thread_block( thread_ptr , THREAD_BLOCKED_USERSYNC ); 276 sched_yield( NULL);276 sched_yield(); 277 277 278 278 // restore interrupts -
trunk/kernel/libk/remote_condvar.c
r296 r407 189 189 // block the calling thread 190 190 thread_block( CURRENT_THREAD , THREAD_BLOCKED_USERSYNC ); 191 sched_yield( NULL);191 sched_yield(); 192 192 193 193 // lock the mutex before return -
trunk/kernel/libk/remote_fifo.c
r296 r407 39 39 uint32_t slot; 40 40 41 fifo->owner = 0; 41 42 fifo->wr_id = 0; 42 43 fifo->rd_id = 0; … … 47 48 } 48 49 49 ////////////////////////////////////////////// 50 error_t remote_fifo_put_item( xptr_t fifo, 51 uint64_t item, 52 bool_t * first ) 50 ///////////////////////////////////////////////// 51 error_t remote_fifo_put_item( xptr_t fifo_xp, 52 uint64_t item ) 53 53 { 54 54 uint32_t wr_id; … … 56 56 uint32_t ptw; 57 57 uint32_t watchdog; 58 reg_t save_sr;59 58 uint32_t nslots; 60 59 61 60 // get remote cluster identifier and pointer on FIFO 62 cxy_t cxy = (cxy_t)GET_CXY( fifo);63 remote_fifo_t * ptr = (remote_fifo_t *)GET_PTR( fifo);61 cxy_t fifo_cxy = (cxy_t)GET_CXY( fifo_xp ); 62 remote_fifo_t * fifo_ptr = (remote_fifo_t *)GET_PTR( fifo_xp ); 64 63 65 64 // initialise watchdog for contention detection 66 65 watchdog = 0; 67 66 68 // no descheduling during put access 69 hal_disable_irq( &save_sr ); 70 71 // get write slot index and atomic increment 72 wr_id = hal_remote_atomic_add( XPTR( cxy , &ptr->wr_id ) , 1 ); 67 // get write slot index with atomic increment 68 wr_id = hal_remote_atomic_add( XPTR( fifo_cxy , &fifo_ptr->wr_id ) , 1 ); 73 69 74 // check fifo state 70 // wait until allocated slot is empty in remote FIFO 71 // max retry = CONFIG_REMOTE_FIFO_MAX_ITERATIONS 72 // return error if watchdog is reached 75 73 while( 1 ) 76 74 { 77 75 // return error if contention detected by watchdog 78 if( watchdog > CONFIG_REMOTE_FIFO_MAX_ITERATIONS ) 79 { 80 // restore scheduling 81 hal_restore_irq( save_sr ); 82 83 // return error 84 return EBUSY; 85 } 76 if( watchdog > CONFIG_REMOTE_FIFO_MAX_ITERATIONS ) return EBUSY; 86 77 87 78 // read remote rd_id value 88 rd_id = hal_remote_lw( XPTR( cxy , &ptr->rd_id ) );79 rd_id = hal_remote_lw( XPTR( fifo_cxy , &fifo_ptr->rd_id ) ); 89 80 90 81 // compute number of full slots … … 92 83 else nslots = (0xFFFFFFFF - rd_id) + wr_id; 93 84 94 // exit iffifo not full85 // exit waiting loop as soon as fifo not full 95 86 if ( nslots < CONFIG_REMOTE_FIFO_SLOTS ) break; 96 87 97 // restore interrupts 98 hal_restore_irq( save_sr ); 99 100 // deschedule without blocking 101 if( thread_can_yield() ) sched_yield( NULL ); 102 103 // disable interrupts 104 hal_disable_irq( &save_sr ); 88 // retry later if fifo full: 89 // - deschedule without blocking if possible 90 // - wait ~1000 cycles otherwise 91 if( thread_can_yield() ) sched_yield(); 92 else hal_fixed_delay( 1000 ); 105 93 106 94 // increment watchdog … … 112 100 113 101 // copy item to fifo 114 hal_remote_swd( XPTR( cxy , &ptr->data[ptw] ), item ); 115 102 hal_remote_swd( XPTR( fifo_cxy , &fifo_ptr->data[ptw] ), item ); 116 103 hal_fence(); 117 104 118 105 // set the slot valid flag 119 hal_remote_sw( XPTR( cxy , &ptr->valid[ptw] ) , 1 );106 hal_remote_sw( XPTR( fifo_cxy , &fifo_ptr->valid[ptw] ) , 1 ); 120 107 hal_fence(); 121 122 // return the first RPC flag123 *first = ( wr_id == rd_id );124 125 // restore scheduling126 hal_restore_irq( save_sr );127 108 128 109 return 0; -
trunk/kernel/libk/remote_fifo.h
r279 r407 28 28 #include <kernel_config.h> 29 29 #include <hal_types.h> 30 #include <printk.h> 30 31 #include <errno.h> 31 32 #include <hal_remote.h> 32 33 33 34 /************************************************************************************ 34 * This structure defines a generic, single reader, multiple writers 35 * remote FIFO, that is used by the RPCs for inter cluster communications. 36 * The accesses are implemented using a lock-free algorithm, as it uses a ticket 37 * based mechanism to handle concurrent access between multiple writers. 38 * Each FIF0 slot can contain one 64 bits integer. 39 * In case of FIFO full, the writer deschedule without blocking, to retry later. 40 * 41 * WARNING : the number of slots is statically defined by the global 42 * configuration parameter CONFIG_REMOTE_FIFO_SLOTS for all fifos. requiring 43 * Each FIFO requires 8 + (12 * CONFIG_REMOTE_FIFO_SLOTS) bytes. 35 * This structure defines a generic, single reader, multiple writers FIFO, 36 * that is used for - RPC based - inter cluster communications. 37 * Each FIF0 slot can contain one 64 bits integer (or one extended pointer). 38 * The number of slots is defined by the CONFIG_REMOTE_FIFO_SLOTS parameter. 39 * - The write accesses are implemented using a lock-free algorithm, as it uses 40 * a ticket based mechanism to handle concurrent access between multiple writers. 41 * In case of FIFO full, the writer deschedule without blocking, to retry later. 42 * - The reader must take the try_lock implemented by the "owner" field, using 43 * an atomic_add(). The TRDID is a good owner identifier, because all 44 * RPC threads in a given cluster belong to the same kernel process, 45 * and RPC threads cannot have local index LTID = 0. 46 * 47 * WARNING : Each FIFO requires 12 + (12 * CONFIG_REMOTE_FIFO_SLOTS) bytes. 44 48 ***********************************************************************************/ 45 49 46 50 typedef struct remote_fifo_s 47 51 { 52 uint32_t owner; /*! owner thread trdid */ 48 53 volatile uint32_t wr_id; /*! write slot index */ 49 54 volatile uint32_t rd_id; /*! read slot index */ … … 63 68 /************************************************************************************ 64 69 * This non blocking function tries to get one item from the local fifo. 65 * The reader must get exclusive access before calling this function.70 * The reader must get exclusive access for read before calling this function. 66 71 * The read slot index is incremented. 67 72 ************************************************************************************ … … 75 80 /************************************************************************************ 76 81 * This blocking function puts one item to a remote fifo identified 77 * by an extended pointer. 78 * This function gets a write ticket using a remote_atomic_increment on the 79 * write slot. Then, it waits until the slot is empty, using a descheduling 80 * policy without blocking. 82 * by an extended pointer. It gets a write ticket on the slot to be written, 83 * using a remote_atomic_add() on the write slot index. Then, it waits until 84 * the slot is empty, using a descheduling policy without blocking if required. 85 * It implements a watchdog, returning when the item has been successfully 86 * registered, or after CONFIG_REMOTE_FIFO_MAX_ITERATIONS failures. 81 87 ************************************************************************************ 82 88 * @ fifo : extended pointer to the fifo in remote cluster. 83 89 * @ item : item to be stored. 84 * @ first : [out] true if first item registered in remote fifo.85 90 * @ return 0 on success / EBUSY if a contention has been detected. 86 91 ***********************************************************************************/ 87 92 error_t remote_fifo_put_item( xptr_t fifo, 88 uint64_t item, 89 bool_t * first ); 93 uint64_t item ); 90 94 91 95 /************************************************************************************ -
trunk/kernel/libk/remote_mutex.c
r296 r407 208 208 // block & deschedule the calling thread 209 209 thread_block( thread_ptr , THREAD_BLOCKED_USERSYNC ); 210 sched_yield( NULL);210 sched_yield(); 211 211 212 212 // restore interrupts -
trunk/kernel/libk/remote_sem.c
r296 r407 219 219 // block and deschedule 220 220 thread_block( this , THREAD_BLOCKED_SEM ); 221 sched_yield( NULL);221 sched_yield(); 222 222 } 223 223 } // end remote_sem_wait() -
trunk/kernel/libk/remote_spinlock.c
r337 r407 179 179 { 180 180 hal_restore_irq( mode ); 181 if( thread_can_yield() ) sched_yield( NULL);181 if( thread_can_yield() ) sched_yield(); 182 182 hal_disable_irq( &mode ); 183 183 continue; -
trunk/kernel/libk/spinlock.c
r337 r407 111 111 { 112 112 hal_restore_irq( mode ); 113 if( thread_can_yield() ) sched_yield( NULL);113 if( thread_can_yield() ) sched_yield(); 114 114 hal_disable_irq( &mode ); 115 115 continue; -
trunk/kernel/mm/kcm.c
r406 r407 47 47 kcm_page_t * kcm_page ) 48 48 { 49 kcm_dmsg("\n[D MSG] %s : enters for %s / page %x / count = %d / active = %d\n",49 kcm_dmsg("\n[DBG] %s : enters for %s / page %x / count = %d / active = %d\n", 50 50 __FUNCTION__ , kmem_type_str( kcm->type ) , 51 51 (intptr_t)kcm_page , kcm_page->count , kcm_page->active ); … … 80 80 + (index * kcm->block_size) ); 81 81 82 kcm_dmsg("\n[D MSG] %s : allocated one block %s / ptr = %p / page = %x / count = %d\n",82 kcm_dmsg("\n[DBG] %s : allocated one block %s / ptr = %p / page = %x / count = %d\n", 83 83 __FUNCTION__ , kmem_type_str( kcm->type ) , ptr , 84 84 (intptr_t)kcm_page , kcm_page->count ); … … 231 231 kcm->blocks_nr = blocks_nr; 232 232 233 kcm_dmsg("\n[D MSG] %s : KCM %s initialised / block_size = %d / blocks_nr = %d\n",233 kcm_dmsg("\n[DBG] %s : KCM %s initialised / block_size = %d / blocks_nr = %d\n", 234 234 __FUNCTION__ , kmem_type_str( type ) , kcm->block_size , kcm->blocks_nr ); 235 235 } … … 301 301 kcm_page->active = 1; 302 302 303 kcm_dmsg("\n[D MSG] %s : enters for type %s at cycle %d / new page = %x / count = %d\n",303 kcm_dmsg("\n[DBG] %s : enters for type %s at cycle %d / new page = %x / count = %d\n", 304 304 __FUNCTION__ , kmem_type_str( kcm->type ) , hal_get_cycles() , 305 305 (intptr_t)kcm_page , kcm_page->count ); … … 311 311 kcm_page = (kcm_page_t *)LIST_FIRST( &kcm->active_root , kcm_page_t , list ); 312 312 313 kcm_dmsg("\n[D MSG] %s : enters for type %s at cycle %d / page = %x / count = %d\n",313 kcm_dmsg("\n[DBG] %s : enters for type %s at cycle %d / page = %x / count = %d\n", 314 314 __FUNCTION__ , kmem_type_str( kcm->type ) , hal_get_cycles() , 315 315 (intptr_t)kcm_page , kcm_page->count ); -
trunk/kernel/mm/kmem.c
r406 r407 145 145 assert( ((type > 1) && (type < KMEM_TYPES_NR) ) , __FUNCTION__ , "illegal KCM type" ); 146 146 147 kmem_dmsg("\n[D MSG] %s : enters / KCM type %s missing in cluster %x\n",147 kmem_dmsg("\n[DBG] %s : enters / KCM type %s missing in cluster %x\n", 148 148 __FUNCTION__ , kmem_type_str( type ) , local_cxy ); 149 149 … … 169 169 hal_fence(); 170 170 171 kmem_dmsg("\n[D MSG] %s : exit / KCM type %s created in cluster %x\n",171 kmem_dmsg("\n[DBG] %s : exit / KCM type %s created in cluster %x\n", 172 172 __FUNCTION__ , kmem_type_str( type ) , local_cxy ); 173 173 … … 192 192 assert( (type < KMEM_TYPES_NR) , __FUNCTION__ , "illegal KMEM request type" ); 193 193 194 kmem_dmsg("\n[D MSG] %s : enters in cluster %x for type %s\n",194 kmem_dmsg("\n[DBG] %s : enters in cluster %x for type %s\n", 195 195 __FUNCTION__ , local_cxy , kmem_type_str( type ) ); 196 196 … … 210 210 if( flags & AF_ZERO ) page_zero( (page_t *)ptr ); 211 211 212 kmem_dmsg("\n[D MSG] %s : exit in cluster %x for type %s / page = %x / base = %x\n",212 kmem_dmsg("\n[DBG] %s : exit in cluster %x for type %s / page = %x / base = %x\n", 213 213 __FUNCTION__, local_cxy , kmem_type_str( type ) , 214 214 (intptr_t)ptr , (intptr_t)ppm_page2base( ptr ) ); … … 228 228 if( flags & AF_ZERO ) memset( ptr , 0 , size ); 229 229 230 kmem_dmsg("\n[D MSG] %s : exit in cluster %x for type %s / base = %x / size = %d\n",230 kmem_dmsg("\n[DBG] %s : exit in cluster %x for type %s / base = %x / size = %d\n", 231 231 __FUNCTION__, local_cxy , kmem_type_str( type ) , 232 232 (intptr_t)ptr , req->size ); … … 255 255 if( flags & AF_ZERO ) memset( ptr , 0 , kmem_type_size( type ) ); 256 256 257 kmem_dmsg("\n[D MSG] %s : exit in cluster %x for type %s / base = %x / size = %d\n",257 kmem_dmsg("\n[DBG] %s : exit in cluster %x for type %s / base = %x / size = %d\n", 258 258 __FUNCTION__, local_cxy , kmem_type_str( type ) , 259 259 (intptr_t)ptr , kmem_type_size( type ) ); -
trunk/kernel/mm/mapper.c
r406 r407 143 143 error_t error; 144 144 145 mapper_dmsg("\n[DMSG] %s :enters for page %d / mapper %x\n",146 __FUNCTION__, index , mapper );145 mapper_dmsg("\n[DBG] %s : core[%x,%d] enters for page %d / mapper %x\n", 146 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , index , mapper ); 147 147 148 148 thread_t * this = CURRENT_THREAD; … … 170 170 if ( page == NULL ) // missing page => create it and load it from file system 171 171 { 172 mapper_dmsg("\n[DMSG] %s : missing page => load from device\n", __FUNCTION__ ); 172 173 mapper_dmsg("\n[DBG] %s : core[%x,%d] missing page => load from device\n", 174 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid ); 173 175 174 176 // allocate one page from PPM … … 188 190 // initialize the page descriptor 189 191 page_init( page ); 190 page_set_flag( page , PG_INIT ); 191 page_set_flag( page , PG_INLOAD ); 192 page_set_flag( page , PG_INIT | PG_INLOAD ); 192 193 page_refcount_up( page ); 193 194 page->mapper = mapper; … … 215 216 error = vfs_mapper_move_page( page, 216 217 true ); // to mapper 217 218 218 if( error ) 219 219 { … … 231 231 page_clear_flag( page , PG_INLOAD ); 232 232 233 mapper_dmsg("\n[DBG] %s : missing page loaded / ppn = %x\n", 234 __FUNCTION__ , ppm_page2ppn(XPTR(local_cxy,page)) ); 235 233 236 } 234 237 else if( page_is_flag( page , PG_INLOAD ) ) // page is loaded by another thread … … 244 247 245 248 // deschedule 246 sched_yield( NULL);249 sched_yield(); 247 250 } 248 251 } … … 254 257 } 255 258 256 mapper_dmsg("\n[DMSG] %s : exit for page %d / mapper %x / page_desc = %x\n",257 259 mapper_dmsg("\n[DBG] %s : exit for page %d / mapper %x / page_desc = %x\n", 260 __FUNCTION__ , index , mapper , page ); 258 261 259 262 return page; … … 310 313 uint8_t * buf_ptr; // current buffer address 311 314 312 mapper_dmsg("\n[D MSG] %s : enters / to_buf = %d / buffer = %x\n",315 mapper_dmsg("\n[DBG] %s : enters / to_buf = %d / buffer = %x\n", 313 316 __FUNCTION__ , to_buffer , buffer ); 314 317 … … 336 339 else page_count = CONFIG_PPM_PAGE_SIZE; 337 340 338 mapper_dmsg("\n[D MSG] %s : index = %d / offset = %d / count = %d\n",341 mapper_dmsg("\n[DBG] %s : index = %d / offset = %d / count = %d\n", 339 342 __FUNCTION__ , index , page_offset , page_count ); 340 343 … … 351 354 buf_ptr = (uint8_t *)buffer + done; 352 355 353 mapper_dmsg("\n[D MSG] %s : index = %d / buf_ptr = %x / map_ptr = %x\n",356 mapper_dmsg("\n[DBG] %s : index = %d / buf_ptr = %x / map_ptr = %x\n", 354 357 __FUNCTION__ , index , buf_ptr , map_ptr ); 355 358 … … 368 371 } 369 372 370 mapper_dmsg("\n[D MSG] %s : exit for buffer %x\n",373 mapper_dmsg("\n[DBG] %s : exit for buffer %x\n", 371 374 __FUNCTION__, buffer ); 372 375 … … 397 400 uint8_t * buffer_ptr = (uint8_t *)GET_PTR( buffer_xp ); 398 401 399 mapper_dmsg("\n[DMSG] %s :to_buf = %d / buf_cxy = %x / buf_ptr = %x / size = %x\n",400 __FUNCTION__ , to_buffer , buffer_cxy , buffer_ptr, size );402 mapper_dmsg("\n[DBG] %s : core[%x,%d] / to_buf = %d / buf_cxy = %x / buf_ptr = %x / size = %x\n", 403 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, to_buffer, buffer_cxy, buffer_ptr, size ); 401 404 402 405 // compute offsets of first and last bytes in file … … 408 411 uint32_t last = max_byte >> CONFIG_PPM_PAGE_SHIFT; 409 412 410 mapper_dmsg("\n[DMSG] %s :first_page = %d / last_page = %d\n",411 __FUNCTION__ , first, last );413 mapper_dmsg("\n[DBG] %s : core[%x,%d] / first_page = %d / last_page = %d\n", 414 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, first, last ); 412 415 413 416 // compute source and destination clusters … … 438 441 else page_count = CONFIG_PPM_PAGE_SIZE; 439 442 440 mapper_dmsg("\n[DMSG] %s :page_index = %d / offset = %d / bytes = %d\n",441 __FUNCTION__ , index , page_offset, page_count );443 mapper_dmsg("\n[DBG] %s : core[%x;%d] / page_index = %d / offset = %d / bytes = %d\n", 444 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, index, page_offset, page_count ); 442 445 443 446 // get page descriptor … … 470 473 } 471 474 472 mapper_dmsg("\n[DMSG] %s :exit / buf_cxy = %x / buf_ptr = %x / size = %x\n",473 __FUNCTION__ , buffer_cxy , buffer_ptr, size );475 mapper_dmsg("\n[DBG] %s : core_cxy[%x,%d] / exit / buf_cxy = %x / buf_ptr = %x / size = %x\n", 476 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, buffer_cxy, buffer_ptr, size ); 474 477 475 478 return 0; -
trunk/kernel/mm/mapper.h
r315 r407 131 131 * @ to_buffer : mapper -> buffer if true / buffer -> mapper if false. 132 132 * @ file_offset : first byte to move in file. 133 * @ buffer: user space pointer on user buffer.133 * @ u_buf : user space pointer on user buffer. 134 134 * @ size : number of bytes to move. 135 135 * returns O if success / returns EINVAL if error. … … 138 138 bool_t to_buffer, 139 139 uint32_t file_offset, 140 void * buffer,140 void * u_buf, 141 141 uint32_t size ); 142 142 -
trunk/kernel/mm/page.c
r315 r407 46 46 page->mapper = NULL; 47 47 page->index = 0; 48 page->fork_nr = 0;49 48 page->refcount = 0; 50 49 … … 181 180 // deschedule the calling thread 182 181 thread_block( thread , THREAD_BLOCKED_PAGE ); 183 sched_yield( NULL);182 sched_yield(); 184 183 } 185 184 else // page is not locked -
trunk/kernel/mm/page.h
r315 r407 67 67 xlist_entry_t wait_root; /*! root of list of waiting threads (16) */ 68 68 uint32_t refcount; /*! reference counter (4) */ 69 uint32_t fork_nr; /*! number of forked processes(4) */69 uint32_t reserved; /*! UNUSED (4) */ 70 70 spinlock_t lock; /*! only used to set the PG_LOCKED flag (16) */ 71 71 } -
trunk/kernel/mm/ppm.c
r406 r407 154 154 page_t * pages_tbl = ppm->pages_tbl; 155 155 156 assert( !page_is_flag( page , PG_FREE ) , __FUNCTION__ , "page already freed" ); 157 assert( !page_is_flag( page , PG_RESERVED ) , __FUNCTION__ , "freeing reserved page" ); 156 assert( !page_is_flag( page , PG_FREE ) , __FUNCTION__ , 157 "page already released : ppn = %x\n" , ppm_page2ppn(XPTR(local_cxy,page)) ); 158 159 assert( !page_is_flag( page , PG_RESERVED ) , __FUNCTION__ , 160 "reserved page : ppn = %x\n" , ppm_page2ppn(XPTR(local_cxy,page)) ); 158 161 159 162 // update released page descriptor flags … … 201 204 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 202 205 203 assert( (order < CONFIG_PPM_MAX_ORDER) , __FUNCTION__ , "illegal order argument" ); 206 assert( (order < CONFIG_PPM_MAX_ORDER) , __FUNCTION__ , 207 "illegal order argument = %x\n" , order ); 204 208 205 209 page_t * block = NULL; 206 210 207 ppm_dmsg("\n[D MSG] %s : enters / order = %d\n",211 ppm_dmsg("\n[DBG] %s : enters / order = %d\n", 208 212 __FUNCTION__ , order ); 209 213 … … 256 260 spinlock_unlock( &ppm->free_lock ); 257 261 258 ppm_dmsg("\n[D MSG] %s : base = %x / order = %d\n",262 ppm_dmsg("\n[DBG] %s : base = %x / order = %d\n", 259 263 __FUNCTION__ , (uint32_t)ppm_page2base( block ) , order ); 260 264 … … 289 293 290 294 printk("\n*** PPM in cluster %x : %d pages / &pages_tbl = %x / vaddr_base = %x ***\n", 291 295 local_cxy , ppm->pages_nr , (intptr_t)ppm->pages_tbl , (intptr_t)ppm->vaddr_base ); 292 296 293 297 for( order = 0 ; order < CONFIG_PPM_MAX_ORDER ; order++ ) … … 316 320 page_t * page; 317 321 318 for( order=0; order < CONFIG_PPM_MAX_ORDER; order++)322 for( order=0 ; order < CONFIG_PPM_MAX_ORDER ; order++ ) 319 323 { 320 324 if( list_is_empty( &ppm->free_pages_root[order] ) ) continue; -
trunk/kernel/mm/ppm.h
r315 r407 127 127 128 128 /***************************************************************************************** 129 * Get extended pointer on page base from Global PPN.129 * Get extended pointer on page base from global PPN. 130 130 ***************************************************************************************** 131 131 * @ ppn : global physical page number. -
trunk/kernel/mm/vmm.c
r406 r407 58 58 vseg_t * vseg_args; 59 59 vseg_t * vseg_envs; 60 vseg_t * vseg_heap;61 60 intptr_t base; 62 61 intptr_t size; 63 62 64 vmm_dmsg("\n[DMSG] %s : enter for process %x\n", __FUNCTION__ , process->pid ); 63 vmm_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x\n", 64 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , process->pid ); 65 65 66 66 // get pointer on VMM 67 67 vmm_t * vmm = &process->vmm; 68 69 // initialize local list of vsegs 70 vmm->vsegs_nr = 0; 71 list_root_init( &vmm->vsegs_root ); 72 rwlock_init( &vmm->vsegs_lock ); 68 73 69 74 assert( ((CONFIG_VMM_KENTRY_SIZE + CONFIG_VMM_ARGS_SIZE + CONFIG_VMM_ENVS_SIZE) … … 77 82 "STACK zone too small\n"); 78 83 79 // initialize the rwlock protecting the vsegs list80 rwlock_init( &vmm->vsegs_lock );81 82 // initialize local list of vsegs and radix-tree83 vmm->vsegs_nr = 0;84 list_root_init( &vmm->vsegs_root );85 86 84 // register kentry vseg in VMM 87 85 base = CONFIG_VMM_KENTRY_BASE << CONFIG_PPM_PAGE_SHIFT; 88 86 size = CONFIG_VMM_KENTRY_SIZE << CONFIG_PPM_PAGE_SHIFT; 89 87 90 vseg_kentry = vmm_create_vseg( process , base , size , VSEG_TYPE_CODE ); 88 vseg_kentry = vmm_create_vseg( process, 89 VSEG_TYPE_CODE, 90 base, 91 size, 92 0, // file_offset unused 93 0, // file_size unused 94 XPTR_NULL, // mapper_xp unused 95 local_cxy ); 91 96 92 97 assert( (vseg_kentry != NULL) , __FUNCTION__ , "cannot register kentry vseg\n" ); … … 99 104 size = CONFIG_VMM_ARGS_SIZE << CONFIG_PPM_PAGE_SHIFT; 100 105 101 vseg_args = vmm_create_vseg( process , base , size , VSEG_TYPE_DATA ); 102 103 assert( (vseg_args != NULL) , __FUNCTION__ , "cannot register args vseg\n" ); 106 vseg_args = vmm_create_vseg( process, 107 VSEG_TYPE_DATA, 108 base, 109 size, 110 0, // file_offset unused 111 0, // file_size unused 112 XPTR_NULL, // mapper_xp unused 113 local_cxy ); 114 115 assert( (vseg_args != NULL) , __FUNCTION__ , "cannot create args vseg\n" ); 104 116 105 117 vmm->args_vpn_base = base; … … 111 123 size = CONFIG_VMM_ENVS_SIZE << CONFIG_PPM_PAGE_SHIFT; 112 124 113 vseg_envs = vmm_create_vseg( process , base , size , VSEG_TYPE_DATA ); 114 115 assert( (vseg_envs != NULL) , __FUNCTION__ , "cannot register envs vseg\n" ); 125 vseg_envs = vmm_create_vseg( process, 126 VSEG_TYPE_DATA, 127 base, 128 size, 129 0, // file_offset unused 130 0, // file_size unused 131 XPTR_NULL, // mapper_xp unused 132 local_cxy ); 133 134 assert( (vseg_envs != NULL) , __FUNCTION__ , "cannot create envs vseg\n" ); 116 135 117 136 vmm->envs_vpn_base = base; 118 119 // register the heap vseg in VMM120 base = CONFIG_VMM_HEAP_BASE << CONFIG_PPM_PAGE_SHIFT;121 size = (CONFIG_VMM_MMAP_BASE-CONFIG_VMM_HEAP_BASE) << CONFIG_PPM_PAGE_SHIFT;122 123 vseg_heap = vmm_create_vseg( process , base , size , VSEG_TYPE_HEAP );124 125 assert( (vseg_heap != NULL) , __FUNCTION__ , "cannot register heap vseg\n" );126 127 vmm->heap_vpn_base = base;128 137 129 138 // initialize generic page table … … 137 146 138 147 // initialize MMAP allocator 139 vmm->mmap_mgr.vpn_base = CONFIG_VMM_ MMAP_BASE;140 vmm->mmap_mgr.vpn_size = CONFIG_VMM_STACK_BASE - CONFIG_VMM_ MMAP_BASE;141 vmm->mmap_mgr.first_free_vpn = CONFIG_VMM_ MMAP_BASE;148 vmm->mmap_mgr.vpn_base = CONFIG_VMM_HEAP_BASE; 149 vmm->mmap_mgr.vpn_size = CONFIG_VMM_STACK_BASE - CONFIG_VMM_HEAP_BASE; 150 vmm->mmap_mgr.first_free_vpn = CONFIG_VMM_HEAP_BASE; 142 151 uint32_t i; 143 152 for( i = 0 ; i < 32 ; i++ ) list_root_init( &vmm->mmap_mgr.zombi_list[i] ); … … 150 159 hal_fence(); 151 160 152 vmm_dmsg("\n[DMSG] %s : exit for process %x / entry_point = %x\n", 153 __FUNCTION__ , process->pid , process->vmm.entry_point ); 161 vmm_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x / entry_point = %x\n", 162 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , 163 process->pid , process->vmm.entry_point ); 154 164 155 165 } // end vmm_init() 166 167 ////////////////////////////////////// 168 void vmm_display( process_t * process, 169 bool_t mapping ) 170 { 171 vmm_t * vmm = &process->vmm; 172 gpt_t * gpt = &vmm->gpt; 173 174 printk("\n***** VSL and GPT for process %x\n\n", 175 process->pid ); 176 177 // get lock protecting the vseg list 178 rwlock_rd_lock( &vmm->vsegs_lock ); 179 180 // scan the list of vsegs 181 list_entry_t * iter; 182 vseg_t * vseg; 183 LIST_FOREACH( &vmm->vsegs_root , iter ) 184 { 185 vseg = LIST_ELEMENT( iter , vseg_t , list ); 186 printk(" - %s : base = %X / size = %X / npages = %d\n", 187 vseg_type_str( vseg->type ) , vseg->min , vseg->max - vseg->min , vseg->vpn_size ); 188 189 if( mapping ) 190 { 191 vpn_t vpn; 192 ppn_t ppn; 193 uint32_t attr; 194 vpn_t base = vseg->vpn_base; 195 vpn_t size = vseg->vpn_size; 196 for( vpn = base ; vpn < (base+size) ; vpn++ ) 197 { 198 hal_gpt_get_pte( gpt , vpn , &attr , &ppn ); 199 if( attr & GPT_MAPPED ) 200 { 201 printk(" . vpn = %X / attr = %X / ppn = %X\n", vpn , attr , ppn ); 202 } 203 } 204 } 205 } 206 207 // release the lock 208 rwlock_rd_unlock( &vmm->vsegs_lock ); 209 } 156 210 157 211 ////////////////////////////////////////// … … 170 224 rwlock_init( &dst_vmm->vsegs_lock ); 171 225 172 // initialize the dst_vmm vsegs list and the radix tree226 // initialize the dst_vmm vsegs list 173 227 dst_vmm->vsegs_nr = 0; 174 228 list_root_init( &dst_vmm->vsegs_root ); 175 229 176 // loop on src_vmm list of vsegs to create 177 // and register vsegs copies in dst_vmm 230 // initialize generic page table 231 error = hal_gpt_create( &dst_vmm->gpt ); 232 233 if( error ) 234 { 235 printk("\n[ERROR] in %s : cannot initialize page table\n", __FUNCTION__ ); 236 return ENOMEM; 237 } 238 239 // loop on SRC VSL to register vsegs copies in DST VSL 240 // and copy valid PTEs from SRC GPT to DST GPT 178 241 list_entry_t * iter; 179 242 vseg_t * src_vseg; … … 201 264 vseg_init_from_ref( dst_vseg , XPTR( local_cxy , src_vseg ) ); 202 265 203 // register dst_vseg in dst_vmm266 // register dst_vseg in DST VSL 204 267 vseg_attach( dst_vmm , dst_vseg ); 268 269 // copy SRC GPT to DST GPT / set COW for all writable vsegs, but the FILE type 270 bool_t cow = (src_vseg->type != VSEG_TYPE_FILE) && (src_vseg->flags & VSEG_WRITE); 271 error = hal_gpt_copy( &dst_vmm->gpt, 272 &src_vmm->gpt, 273 src_vseg->vpn_base, 274 src_vseg->vpn_size, 275 cow ); 276 if( error ) 277 { 278 printk("\n[ERROR] in %s : cannot copy page GPT\n", __FUNCTION__ ); 279 hal_gpt_destroy( &dst_vmm->gpt ); 280 return ENOMEM; 281 } 205 282 } 206 283 207 284 // release the src_vmm vsegs_lock 208 285 rwlock_wr_unlock( &src_vmm->vsegs_lock ); 209 210 // initialize generic page table211 error = hal_gpt_create( &dst_vmm->gpt );212 213 if( error )214 {215 printk("\n[ERROR] in %s : cannot initialize page table\n", __FUNCTION__ );216 return ENOMEM;217 }218 286 219 287 // initialize STACK allocator … … 222 290 223 291 // initialize MMAP allocator 224 dst_vmm->mmap_mgr.vpn_base = CONFIG_VMM_ MMAP_BASE;225 dst_vmm->mmap_mgr.vpn_size = CONFIG_VMM_STACK_BASE - CONFIG_VMM_ MMAP_BASE;226 dst_vmm->mmap_mgr.first_free_vpn = CONFIG_VMM_ MMAP_BASE;292 dst_vmm->mmap_mgr.vpn_base = CONFIG_VMM_HEAP_BASE; 293 dst_vmm->mmap_mgr.vpn_size = CONFIG_VMM_STACK_BASE - CONFIG_VMM_HEAP_BASE; 294 dst_vmm->mmap_mgr.first_free_vpn = CONFIG_VMM_HEAP_BASE; 227 295 uint32_t i; 228 296 for( i = 0 ; i < 32 ; i++ ) list_root_init( &dst_vmm->mmap_mgr.zombi_list[i] ); … … 242 310 243 311 dst_vmm->entry_point = src_vmm->entry_point; 244 245 // HEAP TODO : new heap for child ???246 dst_vmm->heap_vseg = src_vmm->heap_vseg;247 248 // initialize generic page table249 error = hal_gpt_create( &dst_vmm->gpt );250 251 if( error )252 {253 printk("\n[ERROR] in %s : cannot initialize page table\n", __FUNCTION__ );254 return ENOMEM;255 }256 257 // copy GPT content from src_vmm to dst_vmm, activating "Copy-On-Write"258 // TODO register Copy-On_Write in page descriptors259 bool_t cow = true;260 hal_gpt_copy( &dst_vmm->gpt , &src_vmm->gpt , cow );261 312 262 313 hal_fence(); … … 431 482 } // end vmm_mmap_alloc() 432 483 433 ////////////////////////////////////////////// 434 vseg_t * vmm_create_vseg( process_t * process, 435 intptr_t base, 436 intptr_t size, 437 uint32_t type ) 484 //////////////////////////////////////////////// 485 vseg_t * vmm_create_vseg( process_t * process, 486 vseg_type_t type, 487 intptr_t base, 488 uint32_t size, 489 uint32_t file_offset, 490 uint32_t file_size, 491 xptr_t mapper_xp, 492 cxy_t cxy ) 438 493 { 439 494 vseg_t * vseg; // created vseg pointer … … 442 497 error_t error; 443 498 444 // get pointer on VMM 445 vmm_t * vmm = &process->vmm; 446 447 vmm_dmsg("\n[DMSG] %s : enter for process %x / base = %x / size = %x / type = %s\n", 448 __FUNCTION__ , process->pid , base , size , vseg_type_str(type) ); 499 vmm_dmsg("\n[DBG] %s : core[%x,%d] enters / process %x / base %x / size %x / %s / cxy = %x\n", 500 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , 501 process->pid , base , size , vseg_type_str(type) , cxy ); 502 503 // get pointer on VMM 504 vmm_t * vmm = &process->vmm; 449 505 450 506 // compute base, size, vpn_base, vpn_size, depending on vseg type 451 // we use the VMM specific allocators for STACK and MMAPvsegs507 // we use the VMM specific allocators for "stack", "file", "anon", & "remote" vsegs 452 508 if( type == VSEG_TYPE_STACK ) 453 509 { … … 456 512 if( error ) 457 513 { 458 printk("\n[ERROR] in %s : no vspace for stack vseg / process %x in cluster %x\n",459 514 printk("\n[ERROR] in %s : no space for stack vseg / process %x in cluster %x\n", 515 __FUNCTION__ , process->pid , local_cxy ); 460 516 return NULL; 461 517 } … … 498 554 printk("\n[ERROR] in %s for process %x : new vseg [vpn_base = %x / vpn_size = %x]\n" 499 555 " overlap existing vseg [vpn_base = %x / vpn_size = %x]\n", 500 __FUNCTION__ , process->pid, vpn_base, vpn_size, 501 vseg->vpn_base, vseg->vpn_size ); 556 __FUNCTION__ , process->pid, vpn_base, vpn_size, vseg->vpn_base, vseg->vpn_size ); 502 557 return NULL; 503 558 } … … 508 563 { 509 564 printk("\n[ERROR] in %s for process %x : cannot allocate memory for vseg\n", 510 565 __FUNCTION__ , process->pid ); 511 566 return NULL; 512 567 } 513 568 514 569 // initialize vseg descriptor 515 vseg_init( vseg , base, size , vpn_base , vpn_size , type , local_cxy ); 516 517 // update "heap_vseg" in VMM 518 if( type == VSEG_TYPE_HEAP ) process->vmm.heap_vseg = vseg; 570 vseg_init( vseg, 571 type, 572 base, 573 size, 574 vpn_base, 575 vpn_size, 576 file_offset, 577 file_size, 578 mapper_xp, 579 cxy ); 519 580 520 581 // attach vseg to vmm … … 523 584 rwlock_wr_unlock( &vmm->vsegs_lock ); 524 585 525 vmm_dmsg("\n[DMSG] %s : exit for process %x / vseg [%x, %x] registered\n", 526 __FUNCTION__ , process->pid , vseg->min , vseg->max ); 586 vmm_dmsg("\n[DBG] %s : core[%x,%d] exit / process %x / base %x / size %x / type %s\n", 587 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , 588 process->pid , base , size , vseg_type_str(type) ); 527 589 528 590 return vseg; … … 579 641 vseg_free( vseg ); 580 642 } 581 } 643 } // end vmm_remove_vseg() 582 644 583 645 ////////////////////////////////////////////// … … 655 717 } 656 718 657 /////////////////////////////////////////////////////////////////////////////////////// 719 ////////////////////////////////////////////////////////////////////////////////////////// 658 720 // This low-level static function is called by the vmm_get_vseg() and vmm_resize_vseg() 659 721 // functions. It scan the list of registered vsegs to find the unique vseg containing 660 722 // a given virtual address. 661 /////////////////////////////////////////////////////////////////////////////////////// 723 ////////////////////////////////////////////////////////////////////////////////////////// 662 724 // @ vmm : pointer on the process VMM. 663 725 // @ vaddr : virtual address. 664 726 // @ return vseg pointer if success / return NULL if not found. 665 /////////////////////////////////////////////////////////////////////////////////////// 727 ////////////////////////////////////////////////////////////////////////////////////////// 666 728 static vseg_t * vseg_from_vaddr( vmm_t * vmm, 667 729 intptr_t vaddr ) … … 755 817 756 818 // create new vseg 757 new = vmm_create_vseg( process , addr_min , (vseg->max - addr_max) , vseg->type ); 819 new = vmm_create_vseg( process, 820 vseg->type, 821 addr_min, 822 (vseg->max - addr_max), 823 vseg->file_offset, 824 vseg->file_size, 825 vseg->mapper_xp, 826 vseg->cxy ); 827 758 828 if( new == NULL ) error = EINVAL; 759 829 else error = 0; … … 814 884 } // end vmm_get_vseg() 815 885 886 ////////////////////////////////////////////////////////////////////////////////////// 887 // This static function compute the target cluster to allocate a physical page 888 // for a given <vpn> in a given <vseg>, allocates the page (with an RPC if required) 889 // and returns an extended pointer on the allocated page descriptor. 890 // The vseg cannot have the FILE type. 891 ////////////////////////////////////////////////////////////////////////////////////// 892 static xptr_t vmm_page_allocate( vseg_t * vseg, 893 vpn_t vpn ) 894 { 895 // compute target cluster 896 page_t * page_ptr; 897 cxy_t page_cxy; 898 kmem_req_t req; 899 900 uint32_t type = vseg->type; 901 uint32_t flags = vseg->flags; 902 903 assert( ( type != VSEG_TYPE_FILE ) , __FUNCTION__ , "illegal vseg type\n" ); 904 905 if( flags & VSEG_DISTRIB ) // distributed => cxy depends on vpn LSB 906 { 907 uint32_t x_size = LOCAL_CLUSTER->x_size; 908 uint32_t y_size = LOCAL_CLUSTER->y_size; 909 uint32_t y_width = LOCAL_CLUSTER->y_width; 910 uint32_t index = vpn & ((x_size * y_size) - 1); 911 uint32_t x = index / y_size; 912 uint32_t y = index % y_size; 913 page_cxy = (x<<y_width) + y; 914 } 915 else // other cases => cxy specified in vseg 916 { 917 page_cxy = vseg->cxy; 918 } 919 920 // allocate a physical page from target cluster 921 if( page_cxy == local_cxy ) // target cluster is the local cluster 922 { 923 req.type = KMEM_PAGE; 924 req.size = 0; 925 req.flags = AF_NONE; 926 page_ptr = (page_t *)kmem_alloc( &req ); 927 } 928 else // target cluster is not the local cluster 929 { 930 rpc_pmem_get_pages_client( page_cxy , 0 , &page_ptr ); 931 } 932 933 if( page_ptr == NULL ) return XPTR_NULL; 934 else return XPTR( page_cxy , page_ptr ); 935 936 } // end vmm_page_allocate() 937 816 938 //////////////////////////////////////// 817 939 error_t vmm_get_one_ppn( vseg_t * vseg, … … 820 942 { 821 943 error_t error; 822 cxy_t page_cxy; // physical page cluster944 xptr_t page_xp; // extended pointer on physical page descriptor 823 945 page_t * page_ptr; // local pointer on physical page descriptor 824 946 uint32_t index; // missing page index in vseg mapper … … 828 950 index = vpn - vseg->vpn_base; 829 951 830 vmm_dmsg("\n[DMSG] %s : core[%x,%d] enter for vpn = %x / type = %s / index = %d\n",831 952 vmm_dmsg("\n[DBG] %s : core[%x,%d] enter for vpn = %x / type = %s / index = %d\n", 953 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn, vseg_type_str(type), index ); 832 954 833 955 // FILE type : get the physical page from the file mapper … … 835 957 { 836 958 // get extended pointer on mapper 837 xptr_t 959 xptr_t mapper_xp = vseg->mapper_xp; 838 960 839 961 assert( (mapper_xp != XPTR_NULL), __FUNCTION__, … … 856 978 if ( page_ptr == NULL ) return EINVAL; 857 979 858 page_ cxy = mapper_cxy;980 page_xp = XPTR( mapper_cxy , page_ptr ); 859 981 } 860 982 861 983 // Other types : allocate a physical page from target cluster, 984 // as defined by vseg type and vpn value 862 985 else 863 986 { 864 uint32_t flags = vseg->flags; 865 866 // get target cluster for physical page 867 if( flags & VSEG_DISTRIB ) // depends on VPN LSB 868 { 869 uint32_t x_size = LOCAL_CLUSTER->x_size; 870 uint32_t y_size = LOCAL_CLUSTER->y_size; 871 page_cxy = vpn & ((x_size * y_size) - 1); 872 } 873 else // defined in vseg descriptor 874 { 875 page_cxy = vseg->cxy; 876 } 877 878 // allocate a physical page in target cluster 879 kmem_req_t req; 880 if( page_cxy == local_cxy ) // target cluster is the local cluster 881 { 882 req.type = KMEM_PAGE; 883 req.size = 0; 884 req.flags = AF_NONE; 885 page_ptr = (page_t *)kmem_alloc( &req ); 886 } 887 else // target cluster is not the local cluster 888 { 889 rpc_pmem_get_pages_client( page_cxy , 0 , &page_ptr ); 890 } 891 892 if( page_ptr == NULL ) return ENOMEM; 987 // allocate physical page 988 page_xp = vmm_page_allocate( vseg , vpn ); 989 990 if( page_xp == XPTR_NULL ) return ENOMEM; 893 991 894 992 // initialise missing page from .elf file mapper for DATA and CODE types … … 912 1010 uint32_t elf_offset = vseg->file_offset + offset; 913 1011 914 vmm_dmsg("\n[DMSG] %s : core[%x,%d] for vpn = %x / elf_offset = %x\n",915 1012 vmm_dmsg("\n[DBG] %s : core[%x,%d] for vpn = %x / elf_offset = %x\n", 1013 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn, elf_offset ); 916 1014 917 1015 // compute extended pointer on page base 918 xptr_t base_xp = ppm_page2base( XPTR( page_cxy , page_ptr ));1016 xptr_t base_xp = ppm_page2base( page_xp ); 919 1017 920 1018 // file_size (in .elf mapper) can be smaller than vseg_size (BSS) … … 923 1021 if( file_size < offset ) // missing page fully in BSS 924 1022 { 925 vmm_dmsg("\n[DMSG] %s : core[%x,%d] for vpn = %x / fully in BSS\n",926 927 928 if( page_cxy== local_cxy )1023 vmm_dmsg("\n[DBG] %s : core[%x,%d] for vpn = %x / fully in BSS\n", 1024 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn ); 1025 1026 if( GET_CXY( page_xp ) == local_cxy ) 929 1027 { 930 1028 memset( GET_PTR( base_xp ) , 0 , CONFIG_PPM_PAGE_SIZE ); … … 937 1035 else if( file_size >= (offset + CONFIG_PPM_PAGE_SIZE) ) // fully in mapper 938 1036 { 939 vmm_dmsg("\n[DMSG] %s : core[%x,%d] for vpn = %x / fully in mapper\n", 940 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn ); 1037 1038 vmm_dmsg("\n[DBG] %s : core[%x,%d] for vpn = %x / fully in mapper\n", 1039 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn ); 941 1040 942 1041 if( mapper_cxy == local_cxy ) … … 965 1064 // - (page_size + offset - file_size) bytes from BSS 966 1065 { 967 vmm_dmsg("\n[DMSG] %s : core[%x,%d] for vpn = %x / both mapper & BSS\n" 968 " %d bytes from mapper / %d bytes from BSS\n", 969 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn, 970 file_size - offset , offset + CONFIG_PPM_PAGE_SIZE - file_size ); 1066 1067 vmm_dmsg("\n[DBG] %s : core[%x,%d] for vpn = %x / both mapper & BSS\n" 1068 " %d bytes from mapper / %d bytes from BSS\n", 1069 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn, 1070 file_size - offset , offset + CONFIG_PPM_PAGE_SIZE - file_size ); 971 1071 972 1072 // initialize mapper part … … 993 1093 994 1094 // initialize BSS part 995 if( page_cxy== local_cxy )1095 if( GET_CXY( page_xp ) == local_cxy ) 996 1096 { 997 1097 memset( GET_PTR( base_xp ) + file_size - offset , 0 , … … 1008 1108 1009 1109 // return ppn 1010 *ppn = ppm_page2ppn( XPTR( page_cxy , page_ptr ));1011 1012 vmm_dmsg("\n[DMSG] %s : core[%x,%d] exit for vpn = %x / ppn = %x\n",1013 1110 *ppn = ppm_page2ppn( page_xp ); 1111 1112 vmm_dmsg("\n[DBG] %s : core[%x,%d] exit for vpn = %x / ppn = %x\n", 1113 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , *ppn ); 1014 1114 1015 1115 return 0; … … 1020 1120 error_t vmm_get_pte( process_t * process, 1021 1121 vpn_t vpn, 1022 uint32_t * ret_attr, 1023 ppn_t * ret_ppn ) 1024 { 1025 vseg_t * vseg; // pointer on vseg containing VPN 1026 ppn_t ppn; // physical page number 1027 uint32_t attr; // attributes from GPT entry 1122 bool_t cow, 1123 uint32_t * attr, 1124 ppn_t * ppn ) 1125 { 1126 vseg_t * vseg; // pointer on vseg containing VPN 1127 ppn_t old_ppn; // current PTE_PPN 1128 uint32_t old_attr; // current PTE_ATTR 1129 ppn_t new_ppn; // new PTE_PPN 1130 uint32_t new_attr; // new PTE_ATTR 1131 xptr_t page_xp; // extended pointer on allocated page descriptor 1028 1132 error_t error; 1029 1133 … … 1032 1136 "not called in the reference cluster\n" ); 1033 1137 1034 vmm_dmsg("\n[DMSG] %s : core[%x,%d] enter for vpn = %x in process %x\n",1035 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , process->pid);1138 vmm_dmsg("\n[DBG] %s : core[%x,%d] enter for vpn = %x in process %x / cow = %d\n", 1139 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , process->pid , %d); 1036 1140 1037 1141 // get VMM pointer 1038 1142 vmm_t * vmm = &process->vmm; 1039 1143 1040 // access GPT to get PTE attributes and PPN 1041 hal_gpt_get_pte( &vmm->gpt , vpn , &attr , &ppn ); 1042 1043 // if PTE is unmapped 1044 // 1) get VSEG containing the missing VPN 1045 // 2) get & initialize physical page (depending on vseg type), 1046 // 3) register the PTE in reference GPT 1047 if( (attr & GPT_MAPPED) == 0 ) 1048 { 1049 vmm_dmsg("\n[DMSG] %s : core[%x,%d] page %x unmapped => try to map it\n", 1050 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn ); 1051 1052 // 1. get vseg pointer 1053 error = vmm_get_vseg( process , vpn<<CONFIG_PPM_PAGE_SHIFT , &vseg ); 1144 // get vseg pointer from ref VSL 1145 error = vmm_get_vseg( process , vpn<<CONFIG_PPM_PAGE_SHIFT , &vseg ); 1146 1147 if( error ) 1148 { 1149 printk("\n[ERROR] in %s : out of segment / process = %x / vpn = %x\n", 1150 __FUNCTION__ , process->pid , vpn ); 1151 return error; 1152 } 1153 1154 vmm_dmsg("\n[DBG] %s : core[%x,%d] found vseg %s / vpn_base = %x / vpn_size = %x\n", 1155 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , 1156 vseg_type_str(vseg->type) , vseg->vpn_base , vseg->vpn_size ); 1157 1158 // access GPT to get current PTE attributes and PPN 1159 hal_gpt_get_pte( &vmm->gpt , vpn , &old_attr , &old_ppn ); 1160 1161 // for both copy_on_write and page_fault events, we allocate a physical page, 1162 // initialize it, register it in the GPT, and return the new_ppn and new_attr 1163 1164 if( cow ) ////////////// copy_on_write request /////////// 1165 { 1166 assert( (*attr & GPT_MAPPED) , __FUNCTION__ , 1167 "PTE must be mapped for a copy-on-write\n" ); 1168 1169 vmm_dmsg("\n[DBG] %s : core[%x,%d] page %x must be copied => do it\n", 1170 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn ); 1171 1172 // allocate a physical page depending on vseg type 1173 page_xp = vmm_page_allocate( vseg , vpn ); 1174 1175 if( page_xp == XPTR_NULL ) 1176 { 1177 printk("\n[ERROR] in %s : no memory / process = %x / vpn = %x\n", 1178 __FUNCTION__ , process->pid , vpn ); 1179 return ENOMEM; 1180 } 1181 1182 // compute allocated page PPN 1183 new_ppn = ppm_page2ppn( page_xp ); 1184 1185 // copy old page content to new page 1186 xptr_t old_base_xp = ppm_ppn2base( old_ppn ); 1187 xptr_t new_base_xp = ppm_ppn2base( new_ppn ); 1188 memcpy( GET_PTR( new_base_xp ), 1189 GET_PTR( old_base_xp ), 1190 CONFIG_PPM_PAGE_SIZE ); 1191 1192 // update attributes: reset COW and set WRITABLE 1193 new_attr = old_attr & ~GPT_COW; 1194 new_attr = new_attr | GPT_WRITABLE; 1195 1196 // register PTE in GPT 1197 error = hal_gpt_set_pte( &vmm->gpt , vpn , new_ppn , new_attr ); 1054 1198 1055 1199 if( error ) 1056 1200 { 1057 printk("\n[ERROR] in %s : out of segment/ process = %x / vpn = %x\n",1058 1201 printk("\n[ERROR] in %s : cannot update GPT / process = %x / vpn = %x\n", 1202 __FUNCTION__ , process->pid , vpn ); 1059 1203 return error; 1060 1204 } 1061 1062 vmm_dmsg("\n[DMSG] %s : core[%x,%d] found vseg %s / vpn_base = %x / vpn_size = %x\n", 1063 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , 1064 vseg_type_str(vseg->type) , vseg->vpn_base , vseg->vpn_size ); 1065 1066 // 2. get physical page number, depending on vseg type 1067 error = vmm_get_one_ppn( vseg , vpn , &ppn ); 1068 1069 if( error ) 1205 } 1206 else //////////////////// page_fault request /////////// 1207 { 1208 if( (old_attr & GPT_MAPPED) == 0 ) // PTE unmapped in ref GPT 1070 1209 { 1071 printk("\n[ERROR] in %s : cannot allocate memory / process = %x / vpn = %x\n", 1072 __FUNCTION__ , process->pid , vpn ); 1073 return error; 1210 1211 vmm_dmsg("\n[DBG] %s : core[%x,%d] page %x unmapped => try to map it\n", 1212 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn ); 1213 1214 // allocate one physical page, depending on vseg type 1215 error = vmm_get_one_ppn( vseg , vpn , &new_ppn ); 1216 1217 if( error ) 1218 { 1219 printk("\n[ERROR] in %s : no memory / process = %x / vpn = %x\n", 1220 __FUNCTION__ , process->pid , vpn ); 1221 return error; 1222 } 1223 1224 // define attributes from vseg flags 1225 new_attr = GPT_MAPPED | GPT_SMALL; 1226 if( vseg->flags & VSEG_USER ) new_attr |= GPT_USER; 1227 if( vseg->flags & VSEG_WRITE ) new_attr |= GPT_WRITABLE; 1228 if( vseg->flags & VSEG_EXEC ) new_attr |= GPT_EXECUTABLE; 1229 if( vseg->flags & VSEG_CACHE ) new_attr |= GPT_CACHABLE; 1230 1231 // register PTE in GPT 1232 error = hal_gpt_set_pte( &vmm->gpt , vpn , new_ppn , new_attr ); 1233 1234 if( error ) 1235 { 1236 printk("\n[ERROR] in %s : cannot update GPT / process = %x / vpn = %x\n", 1237 __FUNCTION__ , process->pid , vpn ); 1238 return error; 1239 } 1074 1240 } 1075 1076 // 3. define attributes from vseg flags and register in GPT 1077 attr = GPT_MAPPED | GPT_SMALL; 1078 if( vseg->flags & VSEG_USER ) attr |= GPT_USER; 1079 if( vseg->flags & VSEG_WRITE ) attr |= GPT_WRITABLE; 1080 if( vseg->flags & VSEG_EXEC ) attr |= GPT_EXECUTABLE; 1081 if( vseg->flags & VSEG_CACHE ) attr |= GPT_CACHABLE; 1082 1083 error = hal_gpt_set_pte( &vmm->gpt , vpn , ppn , attr ); 1084 1085 if( error ) 1241 else 1086 1242 { 1087 printk("\n[ERROR] in %s : cannot register PTE / process = %x / vpn = %x\n", 1088 __FUNCTION__ , process->pid , vpn ); 1089 return error; 1243 new_attr = old_attr; 1244 new_ppn = old_ppn; 1090 1245 } 1091 } // end new PTE1092 1093 vmm_dmsg("\n[DMSG] %s : core[%x,%d] exit for vpn = %x / ppn= %x\n",1094 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , ppn);1095 1096 * ret_ppn =ppn;1097 * ret_attr =attr;1246 } 1247 1248 vmm_dmsg("\n[DBG] %s : core[%x,%d] exit for vpn = %x / ppn = %x / attr = %x\n", 1249 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , new_ppn , new_attr ); 1250 1251 *ppn = new_ppn; 1252 *attr = new_attr; 1098 1253 return 0; 1099 1254 … … 1106 1261 uint32_t attr; // missing page attributes 1107 1262 ppn_t ppn; // missing page PPN 1108 error_t error; // return value1263 error_t error; 1109 1264 1110 1265 // get reference process cluster and local pointer … … 1113 1268 1114 1269 // get missing PTE attributes and PPN from reference cluster 1115 if( local_cxy != ref_cxy ) // local cluster is not the reference cluster 1116 { 1117 rpc_vmm_get_pte_client( ref_cxy , ref_ptr , vpn , &attr , &ppn , &error ); 1118 } 1119 else // local cluster is the reference cluster 1120 { 1121 error = vmm_get_pte( process , vpn , &attr , &ppn ); 1270 if( local_cxy != ref_cxy ) 1271 { 1272 rpc_vmm_get_pte_client( ref_cxy, 1273 ref_ptr, 1274 vpn, 1275 false, // page_fault 1276 &attr, 1277 &ppn, 1278 &error ); 1279 1280 // get local VMM pointer 1281 vmm_t * vmm = &process->vmm; 1282 1283 // update local GPT 1284 error |= hal_gpt_set_pte( &vmm->gpt , vpn , ppn , attr ); 1285 } 1286 else // local cluster is the reference cluster 1287 { 1288 error = vmm_get_pte( process, 1289 vpn, 1290 false, // page-fault 1291 &attr, 1292 &ppn ); 1122 1293 } 1123 1294 … … 1126 1297 } // end vmm_handle_page_fault() 1127 1298 1299 /////////////////////////////////////////////// 1300 error_t vmm_copy_on_write( process_t * process, 1301 vpn_t vpn ) 1302 { 1303 uint32_t attr; // missing page attributes 1304 ppn_t ppn; // missing page PPN 1305 error_t error; 1306 1307 // get reference process cluster and local pointer 1308 cxy_t ref_cxy = GET_CXY( process->ref_xp ); 1309 process_t * ref_ptr = (process_t *)GET_PTR( process->ref_xp ); 1310 1311 // get new PTE attributes and PPN from reference cluster 1312 if( local_cxy != ref_cxy ) 1313 { 1314 rpc_vmm_get_pte_client( ref_cxy, 1315 ref_ptr, 1316 vpn, 1317 true, // copy-on-write 1318 &attr, 1319 &ppn, 1320 &error ); 1321 1322 // get local VMM pointer 1323 vmm_t * vmm = &process->vmm; 1324 1325 // update local GPT 1326 error |= hal_gpt_set_pte( &vmm->gpt , vpn , ppn , attr ); 1327 } 1328 else // local cluster is the reference cluster 1329 { 1330 error = vmm_get_pte( process, 1331 vpn, 1332 true, // copy-on-write 1333 &attr, 1334 &ppn ); 1335 } 1336 1337 return error; 1338 1339 } // end vmm_copy_on_write() 1128 1340 1129 1341 /////////////////////////////////////////// … … 1152 1364 if( local_cxy == GET_CXY( process->ref_xp) ) // calling process is reference process 1153 1365 { 1154 error = vmm_get_pte( process, vpn , &attr , &ppn );1366 error = vmm_get_pte( process, vpn , false , &attr , &ppn ); 1155 1367 } 1156 1368 else // calling process is not reference process … … 1158 1370 cxy_t ref_cxy = GET_CXY( process->ref_xp ); 1159 1371 process_t * ref_ptr = (process_t *)GET_PTR( process->ref_xp ); 1160 rpc_vmm_get_pte_client( ref_cxy , ref_ptr , vpn , &attr , &ppn , &error );1372 rpc_vmm_get_pte_client( ref_cxy , ref_ptr , vpn , false , &attr , &ppn , &error ); 1161 1373 } 1162 1374 -
trunk/kernel/mm/vmm.h
r406 r407 40 40 41 41 /********************************************************************************************* 42 * This structure defines the STACK allocator used by the VMM to dynamically allocate43 * STACK vsegs requested or released by theuser process.44 * This allocator handles a fixed size array of fixed size slots storesin the STACK zone.42 * This structure defines the STACK allocator used by the VMM to dynamically handle 43 * a STACK vseg requested or released by an user process. 44 * This allocator handles a fixed size array of fixed size slots in the STACK zone. 45 45 * The stack size and the number of slots are defined by the CONFIG_VMM_STACK_SIZE, and 46 * CONFIG_ THREAD46 * CONFIG_VMM_STACK_BASE parameters. 47 47 * Each slot can contain one user stack vseg. The first page in the slot is not allocated 48 48 * to detect stack overflow. … … 50 50 * All allocation / release operations are registered in the stack_bitmap, that completely 51 51 * define the STACK zone state. 52 * In this implementation, the max number of slots is 32.53 52 ********************************************************************************************/ 54 53 … … 62 61 63 62 /********************************************************************************************* 64 * This structure defines the MMAP allocator used by the VMM to dynamically allocate63 * This structure defines the MMAP allocator used by the VMM to dynamically handle 65 64 * MMAP vsegs requested or released by an user process. 66 65 * This allocator should be only used in the reference cluster. … … 92 91 * This local VMM provides three main services: 93 92 * 1) It registers all vsegs statically or dynamically defined in the vseg list. 94 * 2) It allocates virtual memory space for the STACKS and MMAP vsegs .93 * 2) It allocates virtual memory space for the STACKS and MMAP vsegs (FILE/ANON/REMOTE). 95 94 * 3) It contains the local copy of the generic page table descriptor. 96 95 ********************************************************************************************/ … … 98 97 typedef struct vmm_s 99 98 { 100 rwlock_t vsegs_lock; /*! lock protecting the vsegs list & radix tree*/99 rwlock_t vsegs_lock; /*! lock protecting the vsegs list */ 101 100 list_entry_t vsegs_root; /*! all vsegs in same process and same cluster */ 102 101 uint32_t vsegs_nr; /*! total number of local vsegs */ … … 107 106 mmap_mgr_t mmap_mgr; /*! embedded MMAP vsegs allocator */ 108 107 109 uint32_t pgfault_nr; /*! page fault counter 108 uint32_t pgfault_nr; /*! page fault counter (instrumentation) */ 110 109 uint32_t u_err_nr; /*! TODO ??? [AG] */ 111 110 uint32_t m_err_nr; /*! TODO ??? [AG] */ … … 119 118 120 119 intptr_t entry_point; /*! main thread entry point */ 121 122 vseg_t * heap_vseg; /*! pointer on local heap vseg descriptor */123 120 } 124 121 vmm_t; 125 122 126 123 /********************************************************************************************* 127 * This structure is used to store the arguments of the mmap() system call.128 ********************************************************************************************/129 130 typedef struct mmap_attr_s131 {132 void * addr; /*! requested virtual address (unused : should be NULL) */133 uint32_t length; /*! requested vseg size (bytes) */134 uint32_t prot; /*! access modes */135 uint32_t flags; /*! only MAP_FILE / MAP_ANON / MAP_PRIVATE / MAP_SHARED */136 fdid_t fdid; /*! file descriptor index (if MAP_FILE is set) */137 int32_t offset; /*! file offset (if MAP_FILE is set) */138 }139 mmap_attr_t;140 141 /*********************************************************************************************142 124 * This function initialises the virtual memory manager attached to an user process. 143 * - It registers the "kentry", "args", "envs" and "heap" vsegs in the vsegs list. 144 * The "code" and "data" vsegs are registered by the elf_load_process() function, 145 * the "stack" vsegs are registered by the thread_user_create() function, and the 146 * "mmap" vsegs are dynamically created by syscalls. 125 * - It initializes the STACK and MMAP allocators. 126 * - It registers the "kentry", "args", "envs" vsegs in the VSL. 127 * - The "code" and "data" vsegs are registered by the elf_load_process() function. 128 * - The "stack" vsegs are dynamically created by the thread_user_create() function. 129 * - The "file", "anon", "remote" vsegs are dynamically created by the mmap() syscalls. 147 130 * - It initializes the generic page table, calling the HAL specific hal_gpt_init() function. 148 * For TSAR it map all pages for the "kentry" vseg, that must be identity mapping. 149 * - It initializes the STAK and MMAP allocators. 131 * - For TSAR it map all pages for the "kentry" vseg, that must be identity mapping. 150 132 * TODO : Any error in this function gives a kernel panic => improve error handling. 151 133 ********************************************************************************************* … … 155 137 156 138 /********************************************************************************************* 157 * This function copies the content of a source VMM to a destination VMM. 139 * This function displays on TXY0 the list or registered vsegs for a given <process>. 140 * If the <mapping> argument is true, it displays for each vesg all mapped PTEs in GPT. 141 ********************************************************************************************* 142 * @ process : pointer on process descriptor. 143 * @ mapping : detailed mapping if true. 144 ********************************************************************************************/ 145 void vmm_display( struct process_s * process, 146 bool_t mapping ); 147 148 /********************************************************************************************* 149 * This function is called by the sys_fork() system call. 150 * It copies the content of a parent process descriptor VMM to a child process VMM. 151 * - All vsegs registered in the source VSL are copied in the destination VSL. 152 * - All PTEs registered in the source GPT are copied in destination GPT. For all writable 153 * PTEs - but the FILE vsegs - the WRITABLE flag is reset and the COW flag is set in 154 * the destination GPT. 158 155 ********************************************************************************************* 159 156 * @ dst_process : pointer on destination process descriptor. … … 187 184 /********************************************************************************************* 188 185 * This function allocates memory for a vseg descriptor, initialises it, and register it 189 * in the VMM of the process. It checks the collision with pre-existing vsegs in VMM. 190 * For STACK and MMAP types vseg, it does not use the base argument, but uses the VMM STACK 191 * and MMAP specific allocators to get a base address in virtual space. 192 * To comply with the "on-demand" paging policy, this function does NOT modify the 193 * page table, and does not allocate physical memory for vseg data. 194 ********************************************************************************************* 195 * @ vmm : pointer on process descriptor. 196 * @ base : vseg base address 197 * @ size : vseg size (bytes) 198 * @ type : vseg type 199 * @ returns pointer on vseg if success / returns NULL if no memory or conflict. 186 * in the VMM of the local process descriptor, that should be the reference process. 187 * For the 'stack", "file", "anon", & "remote" types, it does not use the <base> argument, 188 * but uses the STACK and MMAP virtual memory allocators. 189 * It checks collision with all pre-existing vsegs. 190 * To comply with the "on-demand" paging policy, this function does NOT modify the page table, 191 * and does not allocate physical memory for vseg data. 192 * It should be called by a local thread (could be a RPC thread if the client thread is not 193 * running in the regerence cluster). 194 ********************************************************************************************* 195 * @ process : pointer on local processor descriptor. 196 * @ type : vseg type. 197 * @ base : vseg base address (not used for dynamically allocated vsegs). 198 * @ size : vseg size (bytes). 199 * @ file_offset : offset in file for CODE, DATA, FILE types. 200 * @ file_size : can be smaller than "size" for DATA type. 201 * @ mapper_xp : extended pointer on mapper for CODE, DATA, FILE types. 202 * @ cxy : physical mapping cluster (for non distributed vsegs). 203 * @ returns pointer on vseg if success / returns NULL if no memory, or conflict. 200 204 ********************************************************************************************/ 201 205 vseg_t * vmm_create_vseg( struct process_s * process, 206 vseg_type_t type, 202 207 intptr_t base, 203 intptr_t size, 204 uint32_t type ); 208 uint32_t size, 209 uint32_t file_offset, 210 uint32_t file_size, 211 xptr_t mapper_xp, 212 cxy_t cxy ); 205 213 206 214 /********************************************************************************************* … … 245 253 /********************************************************************************************* 246 254 * This function removes a given region (defined by a base address and a size) from 247 * the VMM of a given process descriptor. This can modify severalvsegs:255 * the VMM of a given process descriptor. This can modify the number of vsegs: 248 256 * (a) if the region is not entirely mapped in an existing vseg, it's an error. 249 257 * (b) if the region has same base and size as an existing vseg, the vseg is removed. … … 251 259 * (d) if the removed region cut the vseg in three parts, it is modified, and a new 252 260 * vseg is created with same type. 261 * FIXME [AG] this function must be called by a thread running in the reference cluster, 262 * and the VMM must be updated in all process descriptors copies. 253 263 ********************************************************************************************* 254 264 * @ process : pointer on process descriptor … … 279 289 280 290 /********************************************************************************************* 281 * This function is called by the generic exception handler when a page fault291 * This function is called by the generic exception handler when a page-fault event 282 292 * has been detected in a given cluster. 293 * - If the local cluster is the reference, it call directly the vmm_get_pte() function. 283 294 * - If the local cluster is not the reference cluster, it send a RPC_VMM_GET_PTE 284 * to the reference cluster to get the missing PTE attributes and PPN, and update 285 * the local page table. 286 * - If the local cluster is the reference, it call directly the vmm_get_pte() function. 295 * to the reference cluster to get the missing PTE attributes and PPN, 296 * and update the local page table. 287 297 ********************************************************************************************* 288 298 * @ process : pointer on process descriptor. … … 294 304 295 305 /********************************************************************************************* 296 * This function returns in the "attr" and "ppn" arguments the PTE associated to a given 297 * VPN for a given process. This function must be called by a thread running in the 298 * reference cluster. To get the PTE from another cluster, use the RPC_VMM_GET_PTE. 299 * The vseg containing the searched VPN should be registered in the reference VMM. 300 * If the PTE in the reference page table is unmapped, this function allocates the missing 301 * physical page from the target cluster defined by the vseg type, initialize it, 302 * and update the reference page table. It calls the RPC_PMEM_GET_PAGES to get and 303 * initialize the missing physical page, if the target cluster is not the reference cluster. 306 * This function is called by the generic exception handler when a copy-on-write event 307 * has been detected in a given cluster. 308 * - If the local cluster is the reference, it call directly the vmm_get_pte() function. 309 * - If the local cluster is not the reference cluster, it send a RPC_VMM_GET_PTE 310 * to the reference cluster to get the missing PTE attributes and PPN, 311 * and update the local page table. 312 ********************************************************************************************* 313 * @ process : pointer on process descriptor. 314 * @ vpn : VPN of the missing PTE. 315 * @ returns 0 if success / returns ENOMEM if no memory. 316 ********************************************************************************************/ 317 error_t vmm_copy_on_write( struct process_s * process, 318 vpn_t vpn ); 319 320 /********************************************************************************************* 321 * This function is called when a new PTE (GPT entry) is required because a "page-fault", 322 * or "copy-on_write" event has been detected for a given <vpn> in a given <process>. 323 * The <cow> argument defines the type of event to be handled. 324 * This function must be called by a thread running in reference cluster, and the vseg 325 * containing the searched VPN should be registered in the reference VMM. 326 * - for an actual page-fault, it allocates the missing physical page from the target cluster 327 * defined by the vseg type, initialize it, and update the reference page table. 328 * - for a copy-on-write, it allocates a new physical page from the target cluster, 329 * initialise it from the old physical page, and update the reference page table. 330 * In both cases, it calls the RPC_PMEM_GET_PAGES to get the new physical page if the 331 * target cluster is not the reference cluster. 332 * It returns in the <attr> and <ppn> arguments the accessed or modified PTE. 304 333 ********************************************************************************************* 305 334 * @ process : [in] pointer on process descriptor. 306 335 * @ vpn : [in] VPN defining the missing PTE. 336 * @ cow : [in] "copy_on_write" if true / "page_fault" if false. 307 337 * @ attr : [out] PTE attributes. 308 338 * @ ppn : [out] PTE ppn. … … 311 341 error_t vmm_get_pte( struct process_s * process, 312 342 vpn_t vpn, 343 bool_t cow, 313 344 uint32_t * attr, 314 345 ppn_t * ppn ); -
trunk/kernel/mm/vseg.c
r406 r407 52 52 if ( vseg_type == VSEG_TYPE_CODE ) return "CODE"; 53 53 else if( vseg_type == VSEG_TYPE_DATA ) return "DATA"; 54 else if( vseg_type == VSEG_TYPE_HEAP ) return "HEAP"; 55 else if( vseg_type == VSEG_TYPE_STACK ) return "STACK"; 54 else if( vseg_type == VSEG_TYPE_STACK ) return "STAK"; 56 55 else if( vseg_type == VSEG_TYPE_ANON ) return "ANON"; 57 56 else if( vseg_type == VSEG_TYPE_FILE ) return "FILE"; 58 else if( vseg_type == VSEG_TYPE_REMOTE ) return "REMOTE"; 59 else if( vseg_type == VSEG_TYPE_KCODE ) return "KCODE"; 60 else if( vseg_type == VSEG_TYPE_KDATA ) return "KDATA"; 61 else if( vseg_type == VSEG_TYPE_KDEV ) return "KDEV"; 57 else if( vseg_type == VSEG_TYPE_REMOTE ) return "REMO"; 62 58 else return "undefined"; 63 59 } … … 87 83 /////////////////////////////////// 88 84 void vseg_init( vseg_t * vseg, 85 vseg_type_t type, 89 86 intptr_t base, 90 intptr_t size,87 uint32_t size, 91 88 vpn_t vpn_base, 92 89 vpn_t vpn_size, 93 uint32_t type, 90 uint32_t file_offset, 91 uint32_t file_size, 92 xptr_t mapper_xp, 94 93 cxy_t cxy ) 95 94 { 96 vseg->type = type; 97 vseg->min = base; 98 vseg->max = base + size; 99 vseg->vpn_base = vpn_base; 100 vseg->vpn_size = vpn_size; 101 vseg->mapper_xp = XPTR_NULL; 102 vseg->cxy = cxy; 95 vseg->type = type; 96 vseg->min = base; 97 vseg->max = base + size; 98 vseg->vpn_base = vpn_base; 99 vseg->vpn_size = vpn_size; 100 vseg->file_offset = file_offset; 101 vseg->file_size = file_size; 102 vseg->mapper_xp = mapper_xp; 103 vseg->cxy = cxy; 103 104 104 105 // set vseg flags depending on type … … 124 125 VSEG_DISTRIB ; 125 126 } 126 else if( type == VSEG_TYPE_HEAP )127 {128 vseg->flags = VSEG_USER |129 VSEG_WRITE |130 VSEG_CACHE |131 VSEG_DISTRIB ;132 }133 127 else if( type == VSEG_TYPE_REMOTE ) 134 128 { … … 141 135 vseg->flags = VSEG_USER | 142 136 VSEG_WRITE | 143 VSEG_CACHE | 144 VSEG_DISTRIB ; 137 VSEG_CACHE; 145 138 } 146 139 else if( type == VSEG_TYPE_FILE ) … … 161 154 VSEG_CACHE | 162 155 VSEG_PRIVATE ; 156 } 157 else if( type == VSEG_TYPE_KDEV ) 158 { 159 vseg->flags = VSEG_WRITE ; 163 160 } 164 161 else … … 171 168 ////////////////////////////////////////// 172 169 void vseg_init_from_ref( vseg_t * vseg, 173 xptr_t ref )170 xptr_t ref_xp ) 174 171 { 175 172 // get remote vseg cluster and pointer 176 cxy_t cxy = (cxy_t )GET_CXY( ref );177 vseg_t * ptr = (vseg_t *)GET_PTR( ref );173 cxy_t cxy = (cxy_t )GET_CXY( ref_xp ); 174 vseg_t * ptr = (vseg_t *)GET_PTR( ref_xp ); 178 175 179 176 // initialize vseg with remote_read access 180 vseg->type = hal_remote_lw ( XPTR( cxy , &ptr->type ) ); 181 vseg->min = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->min ) ); 182 vseg->max = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->max ) ); 183 vseg->vpn_base = hal_remote_lw ( XPTR( cxy , &ptr->vpn_base ) ); 184 vseg->vpn_size = hal_remote_lw ( XPTR( cxy , &ptr->vpn_size ) ); 185 vseg->flags = hal_remote_lw ( XPTR( cxy , &ptr->flags ) ); 186 vseg->mapper_xp = (xptr_t) hal_remote_lwd( XPTR( cxy , &ptr->mapper_xp ) ); 177 vseg->type = hal_remote_lw ( XPTR( cxy , &ptr->type ) ); 178 vseg->min = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->min ) ); 179 vseg->max = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->max ) ); 180 vseg->vpn_base = hal_remote_lw ( XPTR( cxy , &ptr->vpn_base ) ); 181 vseg->vpn_size = hal_remote_lw ( XPTR( cxy , &ptr->vpn_size ) ); 182 vseg->flags = hal_remote_lw ( XPTR( cxy , &ptr->flags ) ); 183 vseg->file_offset = hal_remote_lw ( XPTR( cxy , &ptr->file_offset ) ); 184 vseg->file_size = hal_remote_lw ( XPTR( cxy , &ptr->file_size ) ); 185 vseg->mapper_xp = (xptr_t) hal_remote_lwd( XPTR( cxy , &ptr->mapper_xp ) ); 187 186 } 188 187 -
trunk/kernel/mm/vseg.h
r406 r407 36 36 37 37 /********************************************************************************************** 38 * This enum defines the vseg types 38 * This enum defines the vseg types for an user process. 39 39 *********************************************************************************************/ 40 40 41 enum41 typedef enum 42 42 { 43 VSEG_TYPE_CODE = 0, /*! executable code / private / localized */ 44 VSEG_TYPE_DATA = 1, /*! initialized data / public / distributed */ 45 VSEG_TYPE_HEAP = 2, /*! standard malloc / public / distributed */ 46 VSEG_TYPE_STACK = 3, /*! execution stack / private / localized */ 47 VSEG_TYPE_ANON = 4, /*! anonymous mmap / public / localized */ 48 VSEG_TYPE_FILE = 5, /*! file mmap / public / localized */ 49 VSEG_TYPE_REMOTE = 6, /*! remote mmap / public / localized */ 50 VSEG_TYPE_KCODE = 7, /*! kernel code / private / localized */ 51 VSEG_TYPE_KDATA = 8, /*! kernel data / private / localized */ 52 VSEG_TYPE_KDEV = 9, /*! device segment / public / localized */ 43 VSEG_TYPE_CODE = 0, /*! executable user code / private / localized */ 44 VSEG_TYPE_DATA = 1, /*! initialized user data / public / distributed */ 45 VSEG_TYPE_STACK = 2, /*! execution user stack / private / localized */ 46 VSEG_TYPE_ANON = 3, /*! anonymous mmap / public / localized */ 47 VSEG_TYPE_FILE = 4, /*! file mmap / public / localized */ 48 VSEG_TYPE_REMOTE = 5, /*! remote mmap / public / localized */ 53 49 54 VSEG_TYPES_NR = 10, 55 }; 50 VSEG_TYPE_KDATA = 10, 51 VSEG_TYPE_KCODE = 11, 52 VSEG_TYPE_KDEV = 12, 53 } 54 vseg_type_t; 56 55 57 56 … … 81 80 vpn_t vpn_size; /*! number of pages occupied */ 82 81 uint32_t flags; /*! vseg attributes */ 83 xptr_t mapper_xp; /*! xptr on remote mapper (for types CODE / DATA / FILE)*/84 intptr_t file_offset; /*! vseg offset in file (for types CODE/DATA )*/82 xptr_t mapper_xp; /*! xptr on remote mapper (for types CODE/DATA/FILE) */ 83 intptr_t file_offset; /*! vseg offset in file (for types CODE/DATA/FILE */ 85 84 intptr_t file_size; /*! max segment size in mapper (for type CODE/DATA) */ 86 85 cxy_t cxy; /*! physical mapping (for non distributed vseg) */ … … 125 124 *********************************************************************************************/ 126 125 void vseg_init( vseg_t * vseg, 126 vseg_type_t type, 127 127 intptr_t base, 128 intptr_t size,128 uint32_t size, 129 129 vpn_t vpn_base, 130 130 vpn_t vpn_size, 131 uint32_t type, 131 uint32_t file_offset, 132 uint32_t file_size, 133 xptr_t mapper_xp, 132 134 cxy_t cxy ); 133 135 -
trunk/kernel/syscalls/sys_chdir.c
r301 r407 41 41 process_t * process = this->process; 42 42 43 // get pathname copy in kernel space 44 error = hal_strcpy_from_uspace( kbuf, pathname, CONFIG_VFS_MAX_PATH_LENGTH ); 45 46 if( error ) 43 // check pathname length 44 if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) 47 45 { 48 printk("\n[ERROR] in %s : pathname too long for thread %x in process %x\n", 49 __FUNCTION__ , this->trdid , process->pid ); 46 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); 50 47 this->errno = ENFILE; 51 48 return -1; 52 49 } 50 51 // copy pathname in kernel space 52 hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 53 53 54 54 // get cluster and local pointer on reference process -
trunk/kernel/syscalls/sys_chmod.c
r302 r407 40 40 process_t * process = this->process; 41 41 42 // get pathname copy in kernel space 43 error = hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 44 45 if( error ) 42 // check pathname length 43 if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) 46 44 { 47 45 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); … … 49 47 return -1; 50 48 } 49 50 // copy pathname in kernel space 51 hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 51 52 52 53 // get cluster and local pointer on reference process -
trunk/kernel/syscalls/sys_closedir.c
r23 r407 24 24 #include <hal_types.h> 25 25 #include <vfs.h> 26 #include <printk.h> 26 27 #include <thread.h> 27 #include <printk.h>28 28 #include <process.h> 29 #include <errno.h> 30 #include <syscalls.h> 31 #include <shared_syscalls.h> 29 32 30 /////////////////////////////// //////31 int sys_closedir ( uint32_t file_id)33 /////////////////////////////// 34 int sys_closedir ( DIR * dirp ) 32 35 { 33 error_t error; 34 xptr_t file_xp; // extended pointer on searched directory file descriptor 35 36 thread_t * this = CURRENT_THREAD; 37 process_t * process = this->process; 38 39 // check file_id argument 40 if( file_id >= CONFIG_PROCESS_FILE_MAX_NR ) 41 { 42 printk("\n[ERROR] in %s : illegal file descriptor index %d\n", 43 __FUNCTION__ , file_id ); 44 this->errno = EBADFD; 45 return -1; 46 } 47 48 // get extended pointer on remote file descriptor 49 file_xp = process_fd_get_xptr( process , file_id ); 50 51 if( file_xp == XPTR_NULL ) 52 { 53 printk("\n[ERROR] in %s : undefined file descriptor index = %d\n", 54 __FUNCTION__ , file_id ); 55 this->errno = EBADFD; 56 return -1; 57 } 58 59 // call relevant VFS function 60 error = vfs_close( file_xp , file_id ); 61 62 if( error ) 63 { 64 printk("\n[ERROR] in %s : cannot close the directory = %d\n", 65 __FUNCTION__ , file_id ); 66 this->errno = error; 67 return -1; 68 } 69 70 return 0; 71 36 printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__ ); 37 CURRENT_THREAD->errno = ENOMEM; 38 return -1; 72 39 } // end sys_closedir() -
trunk/kernel/syscalls/sys_creat.c
r23 r407 25 25 #include <vfs.h> 26 26 #include <syscalls.h> 27 #include <shared_syscalls.h> 27 28 28 29 //////////////////////////////////// -
trunk/kernel/syscalls/sys_exec.c
r406 r407 38 38 39 39 ////////////////////////////////////////////////i////////////////////////////////////// 40 // This static function is called by the sys_exec() function to register the .elf41 // pathname in the exec_info structure, from a string stored in user space.42 ////////////////////////////////////////////////i//////////////////////////////////////43 // @ exec_info : pointer on the exec_info structure.44 // @ pathname : string containing the path to the .elf file (user space).45 // return 0 if success / non-zero if one string too long, or too many strings.46 ///////////////////////////////////////////////////////////////////////////////////////47 static error_t process_exec_get_path( exec_info_t * exec_info,48 char * pathname )49 {50 error_t error;51 52 // copy string to exec_info53 error = hal_strcpy_from_uspace( &exec_info->path[0] , pathname ,54 CONFIG_VFS_MAX_PATH_LENGTH );55 if( error )56 return EINVAL;57 58 return 0;59 }60 61 ////////////////////////////////////////////////i//////////////////////////////////////62 40 // This static function is called twice by the sys_exec() function : 63 41 // - to register the main() arguments (args) in the exec_info structure. … … 71 49 // to store the (args) and (envs) strings are configuration parameters. 72 50 /////////////////////////////////////////////////////////////////////////////////////// 73 // @ exec_info : pointer on the exec_info structure.74 // @ is_args : true if called for (args) / false if called for (envs).75 // @ pointers : array of pointers on the strings (in user space).51 // @ exec_info : pointer on the exec_info structure. 52 // @ is_args : true if called for (args) / false if called for (envs). 53 // @ u_pointers : array of pointers on the strings (in user space). 76 54 // @ return 0 if success / non-zero if too many strings or no more memory. 77 55 /////////////////////////////////////////////////////////////////////////////////////// … … 173 151 // This function build an exec_info_t structure containing all informations 174 152 // required to create the new process descriptor and the associated thread. 175 // It calls the static process_exec_get_path() and process_exec_get_strings() functions 176 // to copy the .elf pathname, the main() arguments and the environment variables from 177 // user buffers to the exec_info_t structure, and call the process_make_exec() function. 153 // It calls the process_exec_get_strings() functions to copy the main() arguments and 154 // the environment variables from user buffers to the exec_info_t structure, allocate 155 // and call the process_make_exec() function. 156 // Finally, it destroys the calling thread and process. 157 // TODO : the args & envs arguments are not supported yet : both must be NULL 178 158 ///////////////////////////////////////////////////////////////////////////////////////// 179 int sys_exec( char * filename, // .elf file pathname159 int sys_exec( char * pathname, // .elf file pathname 180 160 char ** args, // process arguments 181 161 char ** envs ) // environment variables 182 162 { 183 exec_info_t exec_info; // structure to pass to process_make_exec() 184 error_t error; 185 paddr_t paddr; 186 163 exec_info_t exec_info; // structure to pass to process_make_exec() 164 error_t error; 165 166 uint64_t tm_start; 167 uint64_t tm_end; 168 169 tm_start = hal_get_cycles(); 170 171 // get pointers on parent process and thread 187 172 thread_t * this = CURRENT_THREAD; 188 173 process_t * process = this->process; 189 190 // check argument fileme 191 error = vmm_v2p_translate( false , filename , &paddr ); 174 pid_t pid = process->pid; 175 176 exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / cycle %d\n", 177 __FUNCTION__, local_cxy, this->core->lid, pid, (uint32_t)hal_get_cycles() ); 178 179 sched_display( 0 ); 180 181 // check pathname length 182 if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) 183 { 184 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); 185 this->errno = ENFILE; 186 return -1; 187 } 188 189 // copy pathname in exec_info structure (kernel space) 190 hal_strcpy_from_uspace( exec_info.path , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 191 // check args argument 192 assert( (args == NULL) , __FUNCTION__ , 193 "args not supported yet\n" ); 194 195 // check envs argument 196 assert( (envs == NULL) , __FUNCTION__ , 197 "args not supported yet\n" ); 198 199 // compute client_cxy (local cluster) and server_cxy (target cluster) 200 cxy_t cxy_server = CXY_FROM_PID( pid ); 201 cxy_t cxy_client = local_cxy; 202 203 // register parent process in exec_info 204 exec_info.parent_xp = process->ref_xp; 205 206 // new process keep the parent process PID 207 exec_info.keep_pid = true; 208 209 // check and store args in exec_info structure if required 210 if( args != NULL ) 211 { 212 if( process_exec_get_strings( &exec_info , true , args ) ) 213 { 214 printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ ); 215 this->errno = error; 216 return -1; 217 } 218 } 219 220 // check and store envs in exec_info structure if required 221 if( envs != NULL ) 222 { 223 if( process_exec_get_strings( &exec_info , false , envs ) ) 224 { 225 printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ ); 226 this->errno = error; 227 return -1; 228 } 229 } 230 231 // call process_make_exec (local or remote) 232 if( cxy_server == cxy_client ) 233 { 234 error = process_make_exec( &exec_info ); 235 } 236 else 237 { 238 rpc_process_exec_client( cxy_server , &exec_info , &error ); 239 } 192 240 193 241 if( error ) 194 242 { 195 printk("\n[ERROR] in %s : filename unmapped\n", __FUNCTION__ ); 196 this->errno = EINVAL; 197 return -1; 198 } 199 200 // check argument fileme 201 error = vmm_v2p_translate( false , args , &paddr ); 202 203 if( error ) 204 { 205 printk("\n[ERROR] in %s : args unmapped\n", __FUNCTION__ ); 206 this->errno = EINVAL; 207 return -1; 208 } 209 210 // check argument fileme 211 error = vmm_v2p_translate( false , envs , &paddr ); 212 213 if( error ) 214 { 215 printk("\n[ERROR] in %s : envs unmapped\n", __FUNCTION__ ); 216 this->errno = EINVAL; 217 return -1; 218 } 219 220 // compute client_cxy (local cluster) and server_cxy (target cluster) 221 cxy_t cxy_server = CXY_FROM_PID( process->pid ); 222 cxy_t cxy_client = local_cxy; 223 bool_t is_local = (cxy_server == cxy_client); 224 225 exec_dmsg("\n[DMSG] %s starts for process %x on core %d in cluster %x" 226 " / target_cluster = %x / cycle %d\n", 227 __FUNCTION__, process->pid , CURRENT_CORE->lid, 228 cxy_client, cxy_server, hal_get_cycles()); 229 230 // register reference parent process in exec_info 231 exec_info.parent_xp = process->ref_xp; 232 233 // check pathname and store it in exec_info structure 234 error = process_exec_get_path( &exec_info , filename ); 235 236 if ( error ) 237 { 238 printk("\n[ERROR] in %s : elf pathname too long\n", __FUNCTION__ ); 243 printk("\n[ERROR] in %s : cannot create new process %x in cluster %x\n", 244 __FUNCTION__, pid, cxy_server ); 239 245 this->errno = error; 240 246 return -1; 241 247 } 242 248 243 // check and store args in exec_info structure 244 error = process_exec_get_strings( &exec_info , true , args ); 245 246 if( error ) 247 { 248 printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ ); 249 this->errno = error; 250 return -1; 251 } 252 253 // check and store envs in exec_info structure 254 error = process_exec_get_strings( &exec_info , false , envs ); 255 256 if( error ) 257 { 258 printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ ); 259 this->errno = error; 260 return -1; 261 } 262 263 exec_dmsg("\n[DMSG] %s starts exec for process %x at cycle %d\n", 264 __FUNCTION__, process->pid, hal_get_cycles() ); 265 266 if( is_local ) error = process_make_exec( &exec_info ); 267 else rpc_process_exec_client( cxy_server , &exec_info , &error ); 268 269 if( error ) 270 { 271 printk("\n[ERROR] in %s : cannot create new process %x\n", 272 __FUNCTION__ , process->pid ); 273 this->errno = error; 274 return -1; 275 } 276 277 exec_dmsg("\n[DMSG] %s completes exec for process %x at cycle %d\n", 278 __FUNCTION__, process->pid , hal_get_cycles() ); 279 280 // delete the calling thread an process 281 thread_kill( CURRENT_THREAD ); 282 process_kill( CURRENT_THREAD->process ); 249 // FIXME delete the local process descriptor 250 // process_kill( process ); 251 252 tm_end = hal_get_cycles(); 253 254 exec_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x / cycle %d\n" 255 " pathname = %s / cost = %d\n", 256 __FUNCTION__, local_cxy, this->core->lid, pid, (uint32_t)tm_start, 257 exec_info.path , (uint32_t)(tm_end - tm_start) ); 283 258 284 259 return 0; -
trunk/kernel/syscalls/sys_fork.c
r406 r407 24 24 #include <kernel_config.h> 25 25 #include <hal_types.h> 26 #include <hal_context.h> 27 #include <hal_switch.h> 26 28 #include <hal_atomic.h> 27 29 #include <errno.h> … … 45 47 pid_t child_pid; // child process identifier 46 48 thread_t * child_thread; // pointer on child main thread descriptor 47 trdid_t child_trdid; // child main thread identifier 48 lid_t child_core_lid; // core local index for the child main thread 49 cxy_t target_cxy; // final target cluster for forked child process 49 cxy_t target_cxy; // target cluster for forked child process 50 50 error_t error; 51 52 uint64_t tm_start; 53 uint64_t tm_end; 54 55 tm_start = hal_get_cycles(); 51 56 52 57 // get pointers on parent process and thread … … 55 60 parent_pid = parent_process->pid; 56 61 62 fork_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / cycle %d\n", 63 __FUNCTION__ , local_cxy , parent_thread->core->lid , parent_pid , (uint32_t)tm_start ); 64 57 65 // check parent process children number 58 66 if( hal_atomic_add( &parent_process->children_nr , 1 ) >= CONFIG_PROCESS_MAX_CHILDREN ) … … 61 69 hal_atomic_add ( &parent_process->children_nr , -1 ); 62 70 return EAGAIN; 63 }64 65 fork_dmsg("\n[DMSG] %s : enters for process %d at cycle [%d]\n",66 __FUNCTION__, parent_process->pid, hal_get_cycles());67 68 // save FPU state in fpu_context if parent process is FPU owner69 // because we want the child process to share the FPU context70 if( CURRENT_CORE->fpu_owner == parent_thread )71 {72 hal_fpu_context_save( parent_thread );73 fork_dmsg("\n[DMSG] %s : save FPU\n", __FUNCTION__);74 71 } 75 72 … … 95 92 } 96 93 97 fork_dmsg("INFO : %s selecttarget_cluster = %x\n",98 __FUNCTION__, target_cxy );94 //printk("\n[DBG] %s : core[%x,%d] for process %x selects target_cluster = %x\n", 95 //__FUNCTION__ , local_cxy , parent_thread->core->lid , parent_pid , target_cxy ); 99 96 100 97 // allocates memory in local cluster for the child process descriptor … … 127 124 128 125 // initialize and register the child process descriptor 129 process_reference_init( child_process , child_pid , parent_pid ); 130 131 fork_dmsg("\n[DMSG] : %s created child process : pid = %x / ppid = %x\n", 132 __FUNCTION__, child_pid , parent_pid ); 126 process_reference_init( child_process , child_pid , XPTR(local_cxy, parent_process) ); 133 127 134 128 // initialises child process standard files structures … … 148 142 XPTR( local_cxy , &parent_process->fd_array ) ); 149 143 150 fork_dmsg("\n[DMSG] %s : duplicated child process from parent process\n",151 __FUNCTION__);152 153 // replicate s virtual memory manager144 //printk("\n[DBG] %s : core[%x,%d] for process %x created child process %x\n", 145 //__FUNCTION__ , local_cxy , parent_thread->core->lid , parent_pid , child_pid ); 146 147 // replicate VMM 154 148 error = vmm_copy( child_process , parent_process ); 155 149 … … 162 156 } 163 157 164 fork_dmsg("\n[DMSG] %s : parent vmm duplicated in child process\n", __FUNCTION__ ); 165 166 // create child main thread descriptor in local cluster 167 error = thread_user_fork( parent_process , &child_thread ); 168 158 //printk("\n[DBG] %s : core[%x,%d] for process %x duplicated vmm in child process\n", 159 //__FUNCTION__ , local_cxy , parent_thread->core->lid , parent_pid ); 160 //vmm_display( parent_process , true ); 161 //vmm_display( child_process , true ); 162 163 // create child main thread in local cluster 164 error = thread_user_fork( child_process, 165 parent_thread->u_stack_size, 166 parent_thread->u_stack_base, 167 &child_thread ); 169 168 if( error ) 170 169 { 171 printk("\n[ERROR] in %s : cannot duplicate thread\n", __FUNCTION__ );170 printk("\n[ERROR] in %s : cannot duplicate main thread\n", __FUNCTION__ ); 172 171 hal_atomic_add( &parent_process->children_nr , -1 ); 173 172 process_destroy( child_process ); … … 175 174 } 176 175 177 // register child thread in child process, and get a TRDID 178 spinlock_lock( &child_process->th_lock ); 179 error = process_register_thread( child_process, child_thread , &child_trdid ); 180 spinlock_unlock( &child_process->th_lock ); 181 182 if( error ) 183 { 184 printk("\n[ERROR] in %s : cannot register thread\n", __FUNCTION__ ); 185 hal_atomic_add ( &parent_process->children_nr , -1 ); 186 thread_destroy( child_thread ); 187 process_destroy( child_process ); 188 return EAGAIN; 189 } 190 191 // get a local core to execute child thread 192 child_core_lid = cluster_select_local_core(); 193 194 // Update child thread descriptor 195 child_thread->core = &LOCAL_CLUSTER->core_tbl[child_core_lid]; 196 child_thread->process = child_process; 197 child_thread->trdid = child_trdid; 198 199 fork_dmsg("\n[DMSG] %s : initialised child main thread\n", __FUNCTION__ ); 200 201 // register local child thread into local child process th_tbl[] 202 // we don't use the th_lock because there is no concurrent access 203 ltid_t ltid = LTID_FROM_TRDID( child_trdid ); 204 child_process->th_tbl[ltid] = child_thread; 205 child_process->th_nr = 1; 206 207 // register child thread in scheduler 208 sched_register_thread( child_thread->core , child_thread ); 209 210 fork_dmsg("\n[DMSG] %s : registered main thread in scheduler\n", __FUNCTION__); 176 //printk("\n[DBG] %s : core[%x,%d] initialised child main thread\n", 177 //__FUNCTION__ , local_cxy , parent_thread->core->lid ); 211 178 212 179 // update DQDT for the child thread 213 180 dqdt_local_update_threads( 1 ); 214 181 215 fork_dmsg("\n[DMSG] %s : completed / parent pid = %x / child pid = %x / at cycle [%d]\n", 216 __FUNCTION__, parent_process->pid, child_process->pid, hal_get_cycles() ); 217 218 return child_process->pid; 182 // set child_thread FPU_context from parent_thread register values 183 // only when the parent process is the FPU owner 184 if( CURRENT_THREAD->core->fpu_owner == parent_thread ) 185 { 186 hal_fpu_context_save( child_thread->fpu_context ); 187 } 188 189 // set child_thread CPU context from parent_thread register values 190 hal_do_cpu_save( child_thread->cpu_context, 191 child_thread, 192 (int)((intptr_t)child_thread - (intptr_t)parent_thread) ); 193 194 195 // from this point, both parent and child threads execute the following code 196 // but child execute it only when it has been unblocked by its parent 197 198 thread_t * current = CURRENT_THREAD; 199 200 if( current == parent_thread ) 201 { 202 // parent_thread unblock child_thread 203 thread_unblock( XPTR( local_cxy , child_thread ) , THREAD_BLOCKED_GLOBAL ); 204 205 tm_end = hal_get_cycles(); 206 207 fork_dmsg("\n[DBG] %s : core[%x,%d] parent_process %x exit / cycle %d\n" 208 " child_process %x / child_thread = %x / cost = %d\n", 209 __FUNCTION__, local_cxy, parent_thread->core->lid, parent_pid, (uint32_t)tm_start, 210 child_pid, child_thread->trdid , (uint32_t)(tm_end - tm_start) ); 211 212 return child_pid; 213 } 214 else // current == child_thread 215 { 216 assert( (current == child_thread) , __FUNCTION__ , 217 "current thread %x is not the child thread %x\n", current , child_thread ); 218 219 fork_dmsg("\n[DBG] %s : core[%x,%d] child process %x exit / cycle %d\n", 220 __FUNCTION__, local_cxy, parent_thread->core->lid, child_pid, (uint32_t)hal_get_cycles() ); 221 222 return 0; 223 } 219 224 220 225 } // end sys_fork() -
trunk/kernel/syscalls/sys_get_cycle.c
r405 r407 1 1 /* 2 * sys_ clock: get calling core cycles count2 * sys_get_cycle.c - get calling core cycles count. 3 3 * 4 4 * Author Alain Greiner (2016,2017) … … 32 32 #include <printk.h> 33 33 34 ////////////////////////////////// 35 int sys_ clock (uint64_t * cycles)34 ////////////////////////////////////// 35 int sys_get_cycle ( uint64_t * cycle ) 36 36 { 37 37 error_t error; 38 38 paddr_t paddr; 39 uint64_t k_cycle s;39 uint64_t k_cycle; 40 40 41 41 thread_t * this = CURRENT_THREAD; … … 43 43 44 44 // check buffer in user space 45 error = vmm_v2p_translate( false , cycle s, &paddr );45 error = vmm_v2p_translate( false , cycle , &paddr ); 46 46 47 47 if( error ) … … 54 54 55 55 // call relevant core function 56 k_cycle s= hal_get_cycles();56 k_cycle = hal_get_cycles(); 57 57 58 58 // copy to user space 59 hal_copy_to_uspace( cycle s , &k_cycles, sizeof(uint64_t) );59 hal_copy_to_uspace( cycle , &k_cycle , sizeof(uint64_t) ); 60 60 61 61 return 0; 62 62 63 } // end sys_ clock()63 } // end sys_get_cycle() -
trunk/kernel/syscalls/sys_mkdir.c
r303 r407 1 1 /* 2 * sys_mkdir.c - Create a new directory 2 * sys_mkdir.c - Create a new directory in file system. 3 3 * 4 4 * Author Alain Greiner (2016,2017) … … 50 50 } 51 51 52 // get pathname copy in kernel space 53 error = hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 54 55 if( error ) 52 // check pathname length 53 if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) 56 54 { 57 55 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); … … 59 57 return -1; 60 58 } 59 60 // copy pathname in kernel space 61 hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 61 62 62 63 // get cluster and local pointer on reference process -
trunk/kernel/syscalls/sys_mkfifo.c
r304 r407 48 48 } 49 49 50 // get pathname copy in kernel space 51 error = hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 52 53 if( error ) 50 // check pathname length 51 if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) 54 52 { 55 53 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); … … 57 55 return -1; 58 56 } 57 58 // copy pathname in kernel space 59 hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 59 60 60 61 // get cluster and local pointer on reference process -
trunk/kernel/syscalls/sys_mmap.c
r23 r407 24 24 25 25 #include <hal_types.h> 26 #include <hal_uspace.h> 27 #include <shared_syscalls.h> 26 28 #include <errno.h> 27 29 #include <thread.h> 28 30 #include <printk.h> 31 #include <mapper.h> 29 32 #include <vfs.h> 30 33 #include <process.h> 31 34 #include <vmm.h> 32 35 33 ////////////////////////////////// /36 ////////////////////////////////// 34 37 int sys_mmap( mmap_attr_t * attr ) 35 38 { 36 printk("\n[WARNING] function %s not implemented\n", __FUNCTION__ ); 37 return 0; 38 /* 39 error_t err; 40 uint_t count; 41 struct thread_s *this; 42 struct process_s *process; 43 struct vfs_file_s *file; 44 mmap_attr_t attr; 45 size_t isize; 46 int retval; 39 vseg_t * vseg; 40 cxy_t vseg_cxy; 41 vseg_type_t vseg_type; 42 mmap_attr_t k_attr; // attributes copy in kernel space 43 xptr_t mapper_xp; 44 error_t error; 45 paddr_t paddr; // unused, but required for user space checking 46 47 uint64_t tm_start; 48 uint64_t tm_end; 49 50 tm_start = hal_get_cycles(); 51 52 thread_t * this = CURRENT_THREAD; 53 process_t * process = this->process; 54 55 // check arguments in user space 56 error = vmm_v2p_translate( false , attr , &paddr ); 57 58 if ( error ) 59 { 60 printk("\n[ERROR] in %s : arguments not in used space = %x\n", 61 __FUNCTION__ , (intptr_t)attr ); 62 this->errno = EINVAL; 63 return -1; 64 } 65 66 // copy arguments from uspace 67 hal_copy_from_uspace( &k_attr , attr , sizeof(mmap_attr_t) ); 68 69 // get fdid, offset, and length arguments 70 uint32_t fdid = k_attr.fdid; 71 uint32_t offset = k_attr.offset; 72 uint32_t length = k_attr.length; 73 74 // get flags 75 bool_t map_fixed = ( (k_attr.flags & MAP_FIXED) != 0 ); 76 bool_t map_anon = ( (k_attr.flags & MAP_ANON) != 0 ); 77 bool_t map_remote = ( (k_attr.flags & MAP_REMOTE) != 0 ); 78 bool_t map_shared = ( (k_attr.flags & MAP_SHARED) != 0 ); 79 bool_t map_private = ( (k_attr.flags & MAP_PRIVATE) != 0 ); 80 81 // MAP_FIXED not supported 82 if( map_fixed ) 83 { 84 printk("\n[ERROR] in %s : MAP_FIXED not supported\n", __FUNCTION__ ); 85 this->errno = EINVAL; 86 return -1; 87 } 88 89 if( map_shared == map_private ) 90 { 91 printk("\n[ERROR] in %s : MAP_SHARED xor MAP_PRIVATE\n", __FUNCTION__ ); 92 this->errno = EINVAL; 93 return -1; 94 } 95 96 // FIXME handle Copy_On_Write for MAP_PRIVATE... 97 98 // get access rigths 99 bool_t prot_read = ( (k_attr.prot & PROT_READ ) != 0 ); 100 bool_t prot_write = ( (k_attr.prot & PROT_WRITE) != 0 ); 101 102 // test mmap type : can be FILE / ANON / REMOTE 103 104 if( (map_anon == false) && (map_remote == false) ) // FILE 105 { 106 // FIXME: handle concurent delete of file by another thread closing it 107 108 if( fdid >= CONFIG_PROCESS_FILE_MAX_NR ) 109 { 110 printk("\n[ERROR] in %s: bad file descriptor = %d\n", __FUNCTION__ , fdid ); 111 this->errno = EBADFD; 112 return -1; 113 } 114 115 // get extended pointer on file descriptor 116 xptr_t file_xp = process_fd_get_xptr( process , fdid ); 117 118 if( file_xp == XPTR_NULL ) 119 { 120 printk("\n[ERROR] in %s: file %d not found\n", __FUNCTION__ , fdid ); 121 this->errno = EBADFD; 122 return -1; 123 } 124 125 // get file cluster and local pointer 126 cxy_t file_cxy = GET_CXY( file_xp ); 127 vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp ); 128 129 // get inode pointer, mapper pointer and file attributes 130 vfs_inode_t * inode_ptr = hal_remote_lpt(XPTR(file_cxy , &file_ptr->inode )); 131 uint32_t file_attr = hal_remote_lw (XPTR(file_cxy , &file_ptr->attr )); 132 mapper_t * mapper_ptr = hal_remote_lpt(XPTR(file_cxy , &file_ptr->mapper)); 133 134 // get file size 135 uint32_t size = hal_remote_lw( XPTR( file_cxy , &inode_ptr->size ) ); 136 137 // chek offset and length arguments 138 if( (offset + length) > size) 139 { 140 printk("\n[ERROR] in %s: offset (%d) + len (%d) >= file's size (%d)\n", 141 __FUNCTION__, k_attr.offset, k_attr.length, size ); 142 this->errno = ERANGE; 143 return -1; 144 } 145 146 // check access rights 147 if( (prot_read && !(file_attr & FD_ATTR_READ_ENABLE)) || 148 (prot_write && !(file_attr & FD_ATTR_WRITE_ENABLE)) ) 149 { 150 printk("\n[ERROR] in %s: prot = %x / file_attr = %x)\n", 151 __FUNCTION__ , k_attr.prot , file_attr ); 152 this->errno = EACCES; 153 return -1; 154 } 155 156 // increment file refcount 157 vfs_file_count_up( file_xp ); 158 159 mapper_xp = XPTR( file_cxy , mapper_ptr ); 160 vseg_type = VSEG_TYPE_FILE; 161 vseg_cxy = file_cxy; 162 } 163 else // ANON or REMOTE 164 { 165 // no mapper for ANON or REMOTE 166 mapper_xp = XPTR_NULL; 167 168 if( map_anon ) 169 { 170 vseg_type = VSEG_TYPE_ANON; 171 vseg_cxy = local_cxy; 172 } 173 else 174 { 175 vseg_type = VSEG_TYPE_REMOTE; 176 vseg_cxy = k_attr.fdid; 47 177 48 this = current_thread; 49 process = this->process; 50 err = EINVAL; 51 file = NULL; 52 53 if((err = cpu_copy_from_uspace(&attr, attr, sizeof(mmap_attr_t)))) 54 { 55 printk(INFO, "%s: failed, copying from uspace @%x\n", 56 __FUNCTION__, 57 attr); 58 59 this->info.errno = EFAULT; 60 return (int)VM_FAILED; 61 } 62 63 if((attr.flags & VM_REG_HEAP) || 64 ((attr.flags & VM_REG_PVSH) == VM_REG_PVSH) || 65 ((attr.flags & VM_REG_PVSH) == 0) || 66 (attr.length == 0) || 67 (attr.offset & PMM_PAGE_MASK) || 68 ((attr.addr != NULL) && (((uint_t)attr.addr & PMM_PAGE_MASK) || 69 (NOT_IN_USPACE(attr.length + (uint_t)attr.addr)) || 70 (NOT_IN_USPACE((uint_t)attr.addr)) ))) 71 { 72 printk(INFO, "%s: failed, we don't like flags (%x), length (%d), or addr (%x)\n", 73 __FUNCTION__, 74 attr.flags, 75 attr.length, 76 attr.addr); 77 78 this->info.errno = EINVAL; 79 return (int)VM_FAILED; 80 } 81 82 if(attr.flags & VM_REG_ANON) 83 { 84 attr.offset = 0; 85 attr.addr = (attr.flags & VM_REG_FIXED) ? attr.addr : NULL; 86 } 87 else 88 { 89 // FIXME: possible concurent delete of file from another bugy thread closing it 90 if((attr.fd >= CONFIG_TASK_FILE_MAX_NR) || (process_fd_lookup(process, attr.fd, &file))) 91 { 92 printk(INFO, "%s: failed, bad file descriptor (%d)\n", 93 __FUNCTION__, 94 attr.fd); 95 96 this->info.errno = EBADFD; 97 return (int)VM_FAILED; 98 } 99 100 //atomic_add(&file->f_count, 1); 101 vfs_file_up(file);//FIXME coalsce access to remote node info 102 103 //FIXME: does we really to get the size... 104 isize = vfs_inode_size_get_remote(file->f_inode.ptr, file->f_inode.cid); 105 if((attr.offset + attr.length) > isize) 106 { 107 printk(INFO, "%s: failed, offset (%d) + len (%d) >= file's size (%d)\n", 108 __FUNCTION__, 109 attr.offset, 110 attr.length, 111 isize); 112 113 this->info.errno = ERANGE; 114 goto SYS_MMAP_FILE_ERR; 115 } 116 117 if(((attr.prot & VM_REG_RD) && !(VFS_IS(file->f_flags, VFS_O_RDONLY))) || 118 ((attr.prot & VM_REG_WR) && !(VFS_IS(file->f_flags, VFS_O_WRONLY))) || 119 ((attr.prot & VM_REG_WR) && (VFS_IS(file->f_flags, VFS_O_APPEND))))// || 120 //(!(attr.prot & VM_REG_RD) && (attr.flags & VM_REG_PRIVATE))) 121 { 122 printk(INFO, "%s: failed, EACCES prot (%x), f_flags (%x)\n", 123 __FUNCTION__, 124 attr.prot, 125 file->f_flags); 126 127 this->info.errno = EACCES; 128 goto SYS_MMAP_FILE_ERR; 129 } 130 } 131 132 retval = (int) vmm_mmap(process, 133 file, 134 attr.addr, 135 attr.length, 136 attr.prot, 137 attr.flags, 138 attr.offset); 139 140 if((retval != (int)VM_FAILED) || (attr.flags & VM_REG_ANON)) 141 return retval; 142 143 SYS_MMAP_FILE_ERR: 144 printk(INFO, "%s: Failed, Droping file count \n", 145 __FUNCTION__); 146 147 vfs_close( file , &count ); 148 149 if(count == 1) process_fd_put( process , attr.fd ); 150 151 return (int)VM_FAILED; 152 */ 178 if( cluster_is_undefined( vseg_cxy ) ) 179 { 180 printk("\n[ERROR] in %s : illegal cxy for MAP_REMOTE\n", __FUNCTION__ ); 181 this->errno = EINVAL; 182 return -1; 183 } 184 } 185 } 186 187 // get reference process cluster and local pointer 188 xptr_t ref_xp = process->ref_xp; 189 cxy_t ref_cxy = GET_CXY( ref_xp ); 190 process_t * ref_ptr = (process_t *)GET_PTR( ref_xp ); 191 192 // create the vseg in reference cluster 193 if( local_cxy == ref_cxy ) 194 { 195 vseg = vmm_create_vseg( process, 196 vseg_type, 197 0, // base address unused for mmap() 198 length, 199 offset, 200 0, // file_size unused for mmap() 201 mapper_xp, 202 vseg_cxy ); 203 } 204 else 205 { 206 rpc_vmm_create_vseg_client( ref_cxy, 207 ref_ptr, 208 vseg_type, 209 0, // base address unused for mmap() 210 length, 211 offset, 212 0, // file size unused for mmap() 213 mapper_xp, 214 vseg_cxy, 215 &vseg ); 216 } 217 218 if( vseg == NULL ) 219 { 220 printk("\n[ERROR] in %s : cannot create vseg\n", __FUNCTION__ ); 221 this->errno = ENOMEM; 222 return -1; 223 } 224 225 // copy vseg base address to user space 226 hal_copy_to_uspace( &attr->addr , &vseg->min , sizeof(intptr_t) ); 227 228 tm_end = hal_get_cycles(); 229 230 syscall_dmsg("\n[DBG] %s : core[%x,%d] created vseg %s in cluster %x / cycle %d\n" 231 " base = %x / length = %x / cost = %d\n", 232 __FUNCTION__, local_cxy , this->core->lid , vseg_type_str(vseg->type) , 233 vseg->cxy , (uint32_t)tm_start , vseg->min , length , (uint32_t)(tm_end - tm_start) ); 234 235 return 0; 236 153 237 } // end sys_mmap() 238 -
trunk/kernel/syscalls/sys_open.c
r305 r407 55 55 } 56 56 57 // get pathname copy in kernel space 58 error = hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 59 60 if( error ) 57 // check pathname length 58 if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) 61 59 { 62 60 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); … … 65 63 } 66 64 65 // copy pathname in kernel space 66 hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 67 67 68 // get cluster and local pointer on reference process 68 69 xptr_t ref_xp = process->ref_xp; … … 70 71 cxy_t ref_cxy = GET_CXY( ref_xp ); 71 72 72 // get extended pointer on cwd inode73 xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );74 75 73 // get the cwd lock in read mode from reference process 76 74 remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) ); 77 75 78 76 // call the relevant VFS function 79 error = vfs_open( cwd_xp,77 error = vfs_open( process, 80 78 kbuf, 81 79 flags, -
trunk/kernel/syscalls/sys_opendir.c
r23 r407 23 23 24 24 #include <hal_types.h> 25 #include <thread.h> 26 #include <process.h> 27 #include <printk.h> 28 #include <errno.h> 25 29 #include <vfs.h> 26 30 #include <syscalls.h> 31 #include <shared_syscalls.h> 27 32 28 33 /////////////////////////////////// 29 int sys_opendir ( char * pathname ) 34 int sys_opendir ( char * pathname, 35 DIR ** dirp ) 30 36 { 31 uint32_t mode = 0; 32 uint32_t flags = O_DIR; 33 34 return sys_open( pathname , flags , mode ); 35 } 37 printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__ ); 38 CURRENT_THREAD->errno = ENOMEM; 39 return -1; 40 } // end sys opendir() -
trunk/kernel/syscalls/sys_pipe.c
r23 r407 36 36 this->errno = ENOSYS; 37 37 return -1; 38 39 38 } -
trunk/kernel/syscalls/sys_read.c
r313 r407 33 33 #include <process.h> 34 34 35 /* TODO: user page(s) need to be locked [AG] */ 35 // TODO: concurrent user page(s) munmap need to be handled [AG] 36 37 // instrumentation 38 extern uint32_t enter_sys_read; 39 extern uint32_t enter_devfs_move; 40 extern uint32_t enter_txt_read; 41 extern uint32_t enter_chdev_cmd; 42 extern uint32_t enter_chdev_server; 43 extern uint32_t enter_tty_cmd; 44 extern uint32_t enter_tty_isr; 45 extern uint32_t exit_tty_isr; 46 extern uint32_t exit_tty_cmd; 47 extern uint32_t exit_chdev_server; 48 extern uint32_t exit_chdev_cmd; 49 extern uint32_t exit_txt_read; 50 extern uint32_t exit_devfs_move; 51 extern uint32_t exit_sys_read; 52 36 53 37 54 ///////////////////////////////// 38 55 int sys_read( uint32_t file_id, 39 void * buf,56 void * vaddr, 40 57 uint32_t count ) 41 58 { … … 43 60 paddr_t paddr; // required for user space checking 44 61 xptr_t file_xp; // remote file extended pointer 62 uint32_t nbytes; // number of bytes actually read 63 64 uint32_t tm_start; 65 uint32_t tm_end; 66 67 tm_start = hal_get_cycles(); 68 69 #if CONFIG_READ_START 70 enter_sys_read = tm_start; 71 #endif 45 72 46 73 thread_t * this = CURRENT_THREAD; … … 51 78 { 52 79 printk("\n[ERROR] in %s : illegal file descriptor index = %d\n", 53 80 __FUNCTION__ , file_id ); 54 81 this->errno = EBADFD; 55 82 return -1; … … 57 84 58 85 // check user buffer in user space 59 error = vmm_v2p_translate( false , buf, &paddr );86 error = vmm_v2p_translate( false , vaddr , &paddr ); 60 87 61 88 if ( error ) 62 89 { 63 90 printk("\n[ERROR] in %s : user buffer unmapped = %x\n", 64 __FUNCTION__ , (intptr_t)buf);91 __FUNCTION__ , (intptr_t)vaddr ); 65 92 this->errno = EINVAL; 66 93 return -1; … … 72 99 if( file_xp == XPTR_NULL ) 73 100 { 74 printk("\n[ERROR] in %s : undefined file descriptor index = %d \n",75 __FUNCTION__ , file_id );101 printk("\n[ERROR] in %s : undefined file descriptor index = %d in process %x\n", 102 __FUNCTION__ , file_id , process->pid ); 76 103 this->errno = EBADFD; 77 104 return -1; … … 86 113 if( (attr & FD_ATTR_READ_ENABLE) == 0 ) 87 114 { 88 printk("\n[ERROR] in %s : file %d not readable \n",89 __FUNCTION__ , file_id );115 printk("\n[ERROR] in %s : file %d not readable in process %x\n", 116 __FUNCTION__ , file_id , process->pid ); 90 117 this->errno = EBADFD; 91 118 return -1; 92 119 } 93 120 94 // transfer count bytes directly from mapper to user buffer 95 error = vfs_user_move( true, // to_buffer 96 file_xp , 97 buf, 98 count ); 121 // get file type 122 vfs_inode_type_t type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type ) ); 99 123 100 if( error ) 124 // action depend on file type 125 if( type == INODE_TYPE_FILE ) // transfer count bytes from file mapper 101 126 { 102 printk("\n[ERROR] in %s cannot read data from file %d\n", 103 __FUNCTION__ , file_id ); 127 nbytes = vfs_user_move( true, // from mapper to buffer 128 file_xp, 129 vaddr, 130 count ); 131 } 132 else if( type == INODE_TYPE_DEV ) // transfer count bytes from device 133 { 134 nbytes = devfs_user_move( true, // from device to buffer 135 file_xp, 136 vaddr, 137 count ); 138 } 139 else 140 { 141 nbytes = 0; 142 panic("file type %d non supported yet", type ); 143 } 144 145 if( nbytes != count ) 146 { 147 printk("\n[ERROR] in %s cannot read data from file %d in process %x\n", 148 __FUNCTION__ , file_id , process->pid ); 104 149 this->errno = error; 105 150 return -1; … … 108 153 hal_fence(); 109 154 110 return 0; 155 tm_end = hal_get_cycles(); 156 157 #if CONFIG_READ_DEBUG 158 exit_sys_read = tm_end; 159 160 printk("\n@@@@@@@@@@@@ timing ro read character %c\n" 161 " - enter_sys_read = %d / delta %d\n" 162 " - enter_devfs_move = %d / delta %d\n" 163 " - enter_txt_read = %d / delta %d\n" 164 " - enter_chdev_cmd = %d / delta %d\n" 165 " - enter_chdev_server = %d / delta %d\n" 166 " - enter_tty_cmd = %d / delta %d\n" 167 " - enter_tty_isr = %d / delta %d\n" 168 " - exit_tty_isr = %d / delta %d\n" 169 " - exit_tty_cmd = %d / delta %d\n" 170 " - exit_chdev_server = %d / delta %d\n" 171 " - exit_chdev_cmd = %d / delta %d\n" 172 " - exit_txt_read = %d / delta %d\n" 173 " - exit_devfs_move = %d / delta %d\n" 174 " - exit_sys_read = %d / delta %d\n", 175 *((char *)(intptr_t)paddr) , 176 enter_sys_read , 0 , 177 enter_devfs_move , enter_devfs_move - enter_sys_read , 178 enter_txt_read , enter_txt_read - enter_devfs_move , 179 enter_chdev_cmd , enter_chdev_cmd - enter_txt_read , 180 enter_chdev_server , enter_chdev_server - enter_chdev_cmd , 181 enter_tty_cmd , enter_tty_cmd - enter_chdev_server , 182 enter_tty_isr , enter_tty_isr - enter_tty_cmd , 183 exit_tty_isr , exit_tty_isr - enter_tty_isr , 184 exit_tty_cmd , exit_tty_cmd - exit_tty_isr , 185 exit_chdev_server , exit_chdev_server - exit_tty_cmd , 186 exit_chdev_cmd , exit_chdev_cmd - exit_chdev_server , 187 exit_txt_read , exit_txt_read - exit_chdev_cmd , 188 exit_devfs_move , exit_devfs_move - exit_txt_read , 189 exit_sys_read , exit_sys_read - exit_devfs_move ); 190 #endif 191 192 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / nbytes = %d / cycle %d\n" 193 " first byte = %c / file_id = %d / cost = %d\n", 194 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , nbytes , tm_start , 195 *((char *)(intptr_t)paddr) , file_id , tm_end - tm_start ); 196 197 return nbytes; 111 198 112 199 } // end sys_read() -
trunk/kernel/syscalls/sys_readdir.c
r23 r407 31 31 #include <process.h> 32 32 #include <syscalls.h> 33 #include <shared_syscalls.h> 33 34 34 /////////////////////////////////////// ///35 int sys_readdir ( uint32_t file_id,36 vfs_dirent_t * dirent)35 /////////////////////////////////////// 36 int sys_readdir( DIR * dirp, 37 struct dirent ** dentp ) 37 38 { 38 error_t error; 39 paddr_t paddr; 40 xptr_t file_xp; // extended pointer on searched directory file descriptor 41 vfs_dirent_t k_dirent; // kernel copy of dirent 42 43 thread_t * this = CURRENT_THREAD; 44 process_t * process = this->process; 45 46 // check file_id argument 47 if( file_id >= CONFIG_PROCESS_FILE_MAX_NR ) 48 { 49 printk("\n[ERROR] in %s : illegal file descriptor index\n", __FUNCTION__ ); 50 this->errno = EBADFD; 51 return -1; 52 } 53 54 // check dirent structure in user space 55 error = vmm_v2p_translate( false , dirent , &paddr ); 56 57 if ( error ) 58 { 59 printk("\n[ERROR] in %s : user buffer for dirent unmapped = %x\n", 60 __FUNCTION__ , (intptr_t)dirent ); 61 this->errno = EFAULT; 62 return -1; 63 } 64 65 // get extended pointer on remote file descriptor 66 file_xp = process_fd_get_xptr( process , file_id ); 67 68 if( file_xp == XPTR_NULL ) 69 { 70 printk("\n[ERROR] in %s : undefined file descriptor index = %d\n", 71 __FUNCTION__ , file_id ); 72 this->errno = EBADFD; 73 return -1; 74 } 75 76 // call the relevant VFS function 77 error = vfs_readdir( file_xp , &k_dirent ); 78 79 if( error ) 80 { 81 printk("\n[ERROR] in %s : cannot access directory %d\n", 82 __FUNCTION__ , file_id ); 83 this->errno = error; 84 return -1; 85 } 86 87 // copy dirent to user space 88 hal_copy_to_uspace( dirent , &k_dirent , sizeof(vfs_dirent_t) ); 89 90 return 0; 91 39 printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__ ); 40 CURRENT_THREAD->errno = ENOMEM; 41 return -1; 92 42 } // end sys_readdir() -
trunk/kernel/syscalls/sys_rmdir.c
r305 r407 40 40 process_t * process = this->process; 41 41 42 // get pathname copy in kernel space 43 error = hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 44 45 if( error ) 42 // check pathname length 43 if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) 46 44 { 47 45 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); 48 46 this->errno = ENFILE; 49 47 return -1; 50 48 } 49 50 // copy pathname in kernel space 51 hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 51 52 52 53 // get cluster and local pointer on reference process -
trunk/kernel/syscalls/sys_signal.c
r406 r407 45 45 this->process->sig_mgr.sigactions[sig_id] = handler; 46 46 47 signal_dmsg("\n[D MSG] %s : handler @%x has been registred for signal %d\n",47 signal_dmsg("\n[DBG] %s : handler @%x has been registred for signal %d\n", 48 48 __FUNCTION__ , handler , sig_id ); 49 49 -
trunk/kernel/syscalls/sys_stat.c
r124 r407 32 32 #include <process.h> 33 33 34 ///////////////////////////////////// /////35 int sys_stat( uint32_t file_id,36 struct vfs_stat_s *stat )34 ///////////////////////////////////// 35 int sys_stat( char * pathname, 36 struct stat * u_stat ) 37 37 { 38 error_t error; 39 paddr_t paddr; 40 struct vfs_stat_s k_stat; 41 xptr_t file_xp; 38 error_t error; 39 paddr_t paddr; 40 struct stat k_stat; // kernel space 41 xptr_t file_xp; 42 char kbuf[CONFIG_VFS_MAX_PATH_LENGTH]; 42 43 43 44 thread_t * this = CURRENT_THREAD; … … 45 46 46 47 // check stat structure in user space 47 error = vmm_v2p_translate( false , stat , &paddr );48 error = vmm_v2p_translate( false , u_stat , &paddr ); 48 49 49 50 if( error ) … … 55 56 } 56 57 57 // get extended pointer on remote file descriptor 58 file_xp = process_fd_get_xptr( process , file_id ); 59 60 if( file_xp == XPTR_NULL ) 58 // check pathname length 59 if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) 61 60 { 62 printk("\n[ERROR] in %s : undefined file descriptor for thread %x in process %x\n", 63 __FUNCTION__ , this->trdid , process->pid ); 64 this->errno = EBADFD; 61 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); 62 this->errno = ENFILE; 65 63 return -1; 66 64 } 67 65 68 // call the relevant VFS function 66 // copy pathname in kernel space 67 hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 68 69 // get cluster and local pointer on reference process 70 xptr_t ref_xp = process->ref_xp; 71 process_t * ref_ptr = (process_t *)GET_PTR( ref_xp ); 72 cxy_t ref_cxy = GET_CXY( ref_xp ); 73 74 // get extended pointer on cwd inode 75 xptr_t cwd_xp = hal_remote_lwd( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) ); 76 77 // get the cwd lock in read mode from reference process 78 remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) ); 79 80 // get extended pointer on remote file descriptor 81 error = vfs_lookup( cwd_xp, 82 pathname, 83 0, 84 &file_xp ); 85 86 // release the cwd lock 87 remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) ); 88 89 if( error ) 90 { 91 printk("\n[ERROR] in %s : cannot found file <%s> for thread %x in process %x\n", 92 __FUNCTION__ , pathname , this->trdid , process->pid ); 93 this->errno = error; 94 return -1; 95 } 96 97 // call VFS function to get stat info 69 98 error = vfs_stat( file_xp, 70 99 &k_stat ); 71 100 if( error ) 72 101 { 73 printk("\n[ERROR] in %s : cannot access file %d for thread %x in process %x\n",74 __FUNCTION__ , file_id , this->trdid , process->pid);102 printk("\n[ERROR] in %s : cannot get stats for file %s\n", 103 __FUNCTION__ , pathname ); 75 104 this->errno = error; 76 105 return -1; 77 106 } 78 107 79 // copy stat to user space80 hal_copy_to_uspace( stat , &k_stat , sizeof(struct vfs_stat_s) );108 // copy k_stat to u_stat 109 hal_copy_to_uspace( u_stat , &k_stat , sizeof(struct stat) ); 81 110 82 111 hal_fence(); -
trunk/kernel/syscalls/sys_thread_create.c
r406 r407 40 40 41 41 42 ////////////////////////////////////////////////////////////////////////////////////////// 43 // This function implements the pthread_create system call 44 ////////////////////////////////////////////////////////////////////////////////////////// 45 int sys_thread_create ( thread_t * new_thread, // [out] argument 46 pthread_attr_t * user_attr, // [in] argument 47 void * start_func, // [in] argument 48 void * start_arg ) // [in] argument 42 /////////////////////////////////////////////////// 43 int sys_thread_create ( pthread_t * trdid_ptr, 44 pthread_attr_t * user_attr, 45 void * start_func, 46 void * start_arg ) 49 47 { 50 pthread_attr_t k _attr;// copy of pthread attributes in kernel space48 pthread_attr_t kern_attr; // copy of pthread attributes in kernel space 51 49 thread_t * parent; // pointer on thread executing the pthread_create 52 50 xptr_t parent_xp; // extended pointer on created thread … … 56 54 process_t * process; // pointer on local process descriptor 57 55 paddr_t paddr; // unused, required by vmm_v2p_translate() 56 cxy_t target_cxy; // target cluster identifier 58 57 error_t error; 59 58 … … 63 62 tm_start = hal_get_cycles(); 64 63 65 // get parent thead pointer, extended pointer, and process pointer64 // get parent thead pointer, extended pointer, and process 66 65 parent = CURRENT_THREAD; 67 66 parent_xp = XPTR( local_cxy , parent ); 68 67 process = parent->process; 69 68 70 // check user_attr in user space 71 error = vmm_v2p_translate( false , user_attr , &paddr ); 69 // check user_attr in user space & copy to kernel space 70 if( user_attr != NULL ) 71 { 72 error = vmm_v2p_translate( false , user_attr , &paddr ); 72 73 73 if( error ) 74 { 75 printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ ); 76 parent->errno = EINVAL; 77 return -1; 78 } 74 if( error ) 75 { 76 printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ ); 77 parent->errno = EINVAL; 78 return -1; 79 } 80 81 hal_copy_from_uspace( &kern_attr , user_attr , sizeof(pthread_attr_t) ); 82 } 79 83 80 84 // check start_func in user space … … 98 102 } 99 103 100 // copy user_attr structure from user space to kernel space 101 hal_copy_from_uspace( &k_attr , user_attr , sizeof(pthread_attr_t) ); 102 103 // check/set "cxy" attribute 104 if( k_attr.attributes & PT_ATTR_CLUSTER_DEFINED ) 104 // check / define attributes an target_cxy 105 if( user_attr != NULL ) // user defined attributes 106 { 107 // check / get target_cxy 108 if( kern_attr.attributes & PT_ATTR_CLUSTER_DEFINED ) 109 { 110 if( cluster_is_undefined( kern_attr.cxy ) ) 111 { 112 printk("\n[ERROR] in %s : illegal target cluster = %x\n", 113 __FUNCTION__ , kern_attr.cxy ); 114 parent->errno = EINVAL; 115 return -1; 116 } 117 target_cxy = kern_attr.cxy; 118 } 119 else 120 { 121 target_cxy = dqdt_get_cluster_for_process(); 122 } 123 } 124 else // set default attributes 105 125 { 106 if( cluster_is_undefined( k_attr.cxy ) ) 107 { 108 printk("\n[ERROR] in %s : illegal target cluster attribute = %x\n", 109 __FUNCTION__ , k_attr.cxy ); 110 parent->errno = EINVAL; 111 return -1; 112 } 113 } 114 else 115 { 116 k_attr.cxy = dqdt_get_cluster_for_process(); 126 kern_attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED; 127 target_cxy = dqdt_get_cluster_for_process(); 117 128 } 118 129 119 130 // create the thread, using a RPC if required 120 // this returns "error", "child ", and "child_xp"131 // this returns "error", "child_ptr", and "child_xp" 121 132 122 if( k_attr.cxy == local_cxy ) // target cluster is local133 if( target_cxy == local_cxy ) // target cluster is local 123 134 { 124 135 // create thread in local cluster … … 126 137 start_func, 127 138 start_arg, 128 &k _attr,139 &kern_attr, 129 140 &child_ptr ); 130 141 … … 133 144 else // target cluster is remote 134 145 { 135 rpc_thread_user_create_client( k_attr.cxy,146 rpc_thread_user_create_client( target_cxy, 136 147 process->pid, 137 148 start_func, 138 149 start_arg, 139 &k _attr,150 &kern_attr, 140 151 &child_xp, 141 152 &error ); … … 152 163 153 164 // returns trdid to user space 154 trdid = hal_remote_lw( XPTR( k_attr.cxy , &child_ptr->trdid ) );155 hal_copy_to_uspace( new_thread, &trdid , sizeof(pthread_t) );165 trdid = hal_remote_lw( XPTR( target_cxy , &child_ptr->trdid ) ); 166 hal_copy_to_uspace( trdid_ptr , &trdid , sizeof(pthread_t) ); 156 167 157 // register new-thread in parent-thread children list if required 158 if( (k_attr.attributes & PT_ATTR_DETACH) == 0 ) 159 thread_child_parent_link( parent_xp , child_xp ); 168 // register child in parent if required 169 if( user_attr != NULL ) 170 { 171 if( (kern_attr.attributes & PT_ATTR_DETACH) == 0 ) 172 thread_child_parent_link( parent_xp , child_xp ); 173 } 174 175 // activate new thread 176 thread_unblock( child_xp , THREAD_BLOCKED_GLOBAL ); 177 178 hal_fence(); 160 179 161 180 tm_end = hal_get_cycles(); 162 181 163 thread_dmsg("\n[DMSG] %s created thread %x for process %x in cluster %x\n" 164 " start_cycle = %d / end_cycle = %d\n", 165 trdid , process->pid , k_attr.cxy , tm_start , tm_end ); 182 syscall_dmsg("\n[DBG] %s : core[%x,%d] created thread %x for process %x / cycle %d\n" 183 " cluster %x / cost = %d cycles\n", 184 __FUNCTION__ , local_cxy , parent->core->lid , trdid , process->pid , tm_end , 185 target_cxy , tm_end - tm_start ); 186 166 187 return 0; 167 }168 188 189 } // end sys_thread_create() 190 -
trunk/kernel/syscalls/sys_thread_exit.c
r296 r407 38 38 reg_t irq_state; 39 39 40 // register the exit_value in thread descriptor40 // register the exit_value pointer in thread descriptor 41 41 this->exit_value = exit_value; 42 42 43 // we enter the join loop to wait the join 44 // only if thread is joinable 43 // enter the join loop to wait the join if thread is joinable 45 44 if( (this->flags & THREAD_FLAG_DETACHED) == 0 ) 46 45 { … … 74 73 75 74 // deschedule 76 sched_yield( NULL);75 sched_yield(); 77 76 } 78 77 } -
trunk/kernel/syscalls/sys_thread_join.c
r296 r407 138 138 139 139 // deschedule 140 sched_yield( NULL);140 sched_yield(); 141 141 } 142 142 } -
trunk/kernel/syscalls/sys_thread_sleep.c
r406 r407 32 32 thread_t * this = CURRENT_THREAD; 33 33 34 thread_dmsg("\n[D MSG] %s : thread %x in process %x goes to sleep at cycle %d\n",34 thread_dmsg("\n[DBG] %s : thread %x in process %x goes to sleep at cycle %d\n", 35 35 __FUNCTION__, this->trdid, this->process->pid, hal_get_cycles() ); 36 36 37 37 thread_block( this , THREAD_BLOCKED_GLOBAL ); 38 sched_yield( NULL);38 sched_yield(); 39 39 40 thread_dmsg("\n[D MSG] %s : thread %x in process %x resume at cycle\n",40 thread_dmsg("\n[DBG] %s : thread %x in process %x resume at cycle\n", 41 41 __FUNCTION__, this->trdid, this->process->pid, hal_get_cycles() ); 42 42 -
trunk/kernel/syscalls/sys_thread_yield.c
r296 r407 27 27 int sys_thread_yield() 28 28 { 29 sched_yield( NULL);29 sched_yield(); 30 30 return 0; 31 31 } -
trunk/kernel/syscalls/sys_timeofday.c
r124 r407 30 30 #include <vmm.h> 31 31 #include <core.h> 32 #include < time.h>32 #include <shared_syscalls.h> 33 33 34 34 //////////////////////////////////////// -
trunk/kernel/syscalls/sys_trace.c
r406 r407 49 49 // desactivate thread trace TODO 50 50 51 printk("\n[D MSG] %s : trace OFF for thread %x in process %x\n",51 printk("\n[DBG] %s : trace OFF for thread %x in process %x\n", 52 52 __FUNCTION__ , trdid , pid ); 53 53 } … … 56 56 // activate thread trace TODO 57 57 58 printk("\n[D MSG] %s : trace ON for thread %x in process %x\n",58 printk("\n[DBG] %s : trace ON for thread %x in process %x\n", 59 59 __FUNCTION__ , trdid , pid ); 60 60 } -
trunk/kernel/syscalls/sys_unlink.c
r305 r407 37 37 process_t * process = this->process; 38 38 39 // get pathname copy in kernel space 40 error = hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 41 42 if( error ) 39 // check pathname length 40 if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) 43 41 { 44 42 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); … … 46 44 return -1; 47 45 } 46 47 // copy pathname in kernel space 48 hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 48 49 49 50 // get cluster and local pointer on reference process -
trunk/kernel/syscalls/sys_write.c
r315 r407 32 32 #include <process.h> 33 33 34 /* TODO: user page(s) need to be locked[AG] */34 /* TODO: concurrent user page(s) unmap need to be handled [AG] */ 35 35 36 36 ////////////////////////////////// 37 37 int sys_write( uint32_t file_id, 38 void * buf,38 void * vaddr, 39 39 uint32_t count ) 40 40 { 41 41 error_t error; 42 paddr_t paddr; // required for user space checking42 paddr_t paddr; // unused, but required for user space checking 43 43 xptr_t file_xp; // remote file extended pointer 44 uint32_t nbytes; // number of bytes actually written 45 46 uint32_t tm_start; 47 uint32_t tm_end; 48 49 tm_start = hal_get_cycles(); 44 50 45 51 thread_t * this = CURRENT_THREAD; … … 55 61 56 62 // check user buffer in user space 57 error = vmm_v2p_translate( false , buf, &paddr );63 error = vmm_v2p_translate( false , vaddr , &paddr ); 58 64 59 65 if ( error ) 60 66 { 61 67 printk("\n[ERROR] in %s : user buffer unmapped = %x\n", 62 __FUNCTION__ , (intptr_t)buf);68 __FUNCTION__ , (intptr_t)vaddr ); 63 69 this->errno = EINVAL; 64 70 return -1; … … 70 76 if( file_xp == XPTR_NULL ) 71 77 { 72 printk("\n[ERROR] in %s : undefined file descriptor index = %d \n",73 __FUNCTION__ , file_id );78 printk("\n[ERROR] in %s : undefined file descriptor index = %d in process %x\n", 79 __FUNCTION__ , file_id , process->pid ); 74 80 this->errno = EBADFD; 75 81 return -1; … … 84 90 if( (attr & FD_ATTR_WRITE_ENABLE) == 0 ) 85 91 { 86 printk("\n[ERROR] in %s : file %d not writable \n",87 __FUNCTION__ , file_id );92 printk("\n[ERROR] in %s : file %d not writable in process %x\n", 93 __FUNCTION__ , file_id , process->pid ); 88 94 this->errno = EBADFD; 89 95 return -1; 90 96 } 91 97 92 // transfer count bytes directly from user buffer to mapper 93 error = vfs_user_move( false, // from buffer 94 file_xp, 95 buf , 96 count ); 98 // get file type 99 vfs_inode_type_t type = hal_remote_lw( XPTR( file_cxy , &file_ptr->type ) ); 97 100 98 if( error ) 101 // action depend on file type 102 if( type == INODE_TYPE_FILE ) // transfer count bytes to file mapper 99 103 { 100 printk("\n[ERROR] in %s cannot read data from file %d\n", 101 __FUNCTION__ , file_id ); 104 nbytes = vfs_user_move( false, // from buffer to mapper 105 file_xp, 106 vaddr, 107 count ); 108 } 109 else if( type == INODE_TYPE_DEV ) // transfer count bytes to device 110 { 111 nbytes = devfs_user_move( false, // from buffer to device 112 file_xp, 113 vaddr, 114 count ); 115 } 116 else 117 { 118 nbytes = 0; 119 panic("file type %d non supported", type ); 120 } 121 122 if( nbytes != count ) 123 { 124 printk("\n[ERROR] in %s cannot write data to file %d in process %x\n", 125 __FUNCTION__ , file_id , process->pid ); 102 126 this->errno = error; 103 127 return -1; … … 106 130 hal_fence(); 107 131 108 return 0; 132 tm_end = hal_get_cycles(); 133 134 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / nbytes = %d / cycle %d\n" 135 " first byte = %c / file_id = %d / cost = %d\n", 136 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , nbytes , tm_start , 137 *((char *)(intptr_t)paddr) , file_id , tm_end - tm_start ); 138 139 return nbytes; 109 140 110 141 } // end sys_write() -
trunk/kernel/syscalls/syscalls.h
r279 r407 1 1 /* 2 * syscalls.h - kernel services definition2 * syscalls.h - Kernel side services for syscall handling. 3 3 * 4 4 * Author Alain Greiner (2016,2017) … … 26 26 27 27 #include <hal_types.h> 28 #include < time.h>29 30 /** ***Forward declarations *****/28 #include <shared_syscalls.h> 29 30 /** Forward declarations *****/ 31 31 32 32 struct thread_s; // defined in thread.h … … 36 36 struct mmap_attr_s; // defined in vmm.h 37 37 38 /****************************************************************************************** 39 * This enum defines the mnemonics for the syscall indexes. 40 * It must be kept consistent with the array defined in do_syscalls.c 41 *****************************************************************************************/ 42 enum 43 { 44 SYS_THREAD_EXIT = 0, 45 SYS_MMAP = 1, 46 SYS_THREAD_CREATE = 2, 47 SYS_THREAD_JOIN = 3, 48 SYS_THREAD_DETACH = 4, 49 SYS_THREAD_YIELD = 5, 50 SYS_SEM = 6, 51 SYS_CONDVAR = 7, 52 SYS_BARRIER = 8, 53 SYS_MUTEX = 9, 54 55 SYS_SLEEP = 10, 56 SYS_WAKEUP = 11, 57 SYS_OPEN = 12, 58 SYS_CREAT = 13, 59 SYS_READ = 14, 60 SYS_WRITE = 15, 61 SYS_LSEEK = 16, 62 SYS_CLOSE = 17, 63 SYS_UNLINK = 18, 64 SYS_PIPE = 19, 65 66 SYS_CHDIR = 20, 67 SYS_MKDIR = 21, 68 SYS_MKFIFO = 22, 69 SYS_OPENDIR = 23, 70 SYS_READDIR = 24, 71 SYS_CLOSEDIR = 25, 72 SYS_GETCWD = 26, 73 SYS_CLOCK = 27, 74 SYS_ALARM = 28, 75 SYS_RMDIR = 29, 76 77 SYS_UTLS = 30, 78 SYS_CHMOD = 31, 79 SYS_SIGNAL = 32, 80 SYS_TIMEOFDAY = 33, 81 SYS_KILL = 34, 82 SYS_GETPID = 35, 83 SYS_FORK = 36, 84 SYS_EXEC = 37, 85 SYS_STAT = 38, 86 SYS_TRACE = 39, 87 88 SYSCALLS_NR = 40, 89 }; 90 91 92 /********************************************************************************************/ 93 /******************** system calls ****************************************************/ 94 /********************************************************************************************/ 95 96 /********************************************************************************************* 97 * [0] This function terminates the execution of the calling user thread value, 38 /****************************************************************************************** 39 * [0] This function terminates the execution of the calling user thread, 98 40 * and makes the exit_value pointer available to any successful pthread_join() with the 99 41 * terminating thread. 100 ****************************************************************************************** ***101 * @ exit_vallue : [out] pointer to to the parrent thread ifattached.102 * @ return 0 if success / return -1 if failure. 103 ***************************************************************************************** ***/42 ****************************************************************************************** 43 * @ exit_vallue : pointer to be returned to parent thread if thead is attached. 44 * @ return 0 if success / return -1 if failure. 45 *****************************************************************************************/ 104 46 int sys_thread_exit( void * exit_value ); 105 47 106 /****************************************************************************************** ***107 * [1] This function map physical memory (or a file) in the calling thread virtual space.108 * The <attr> argument is a pointer on a structure containing arguments, defined in vmm.h.109 * TODO not implemented yet...110 * ********************************************************************************************111 * @ attr : pointer on attributes structure.112 * @ return 0 if success / return -1 if failure.113 ***************************************************************************************** ***/114 int sys_ mmap( struct mmap_attr_s * attr);115 116 /****************************************************************************************** ***48 /****************************************************************************************** 49 * [1] This function calls the scheduler for the core running the calling thread. 50 ****************************************************************************************** 51 * @ x_size : [out] number of clusters in a row. 52 * @ y_size : [out] number of clusters in a column. 53 * @ ncores : [out] number of cores per cluster. 54 * @ return always 0. 55 *****************************************************************************************/ 56 int sys_thread_yield(); 57 58 /****************************************************************************************** 117 59 * [2] This function creates a new user thread. The <user_attr> argument is a pointer 118 60 * on astructure containing the thread attributes, defined in thread.h file. 119 ****************************************************************************************** ***61 ****************************************************************************************** 120 62 * @ new_thread : [out] local pointer on created thread descriptor. 121 63 * @ user_attr : [in] pointer on thread attributes structure. … … 123 65 * @ start_args : [in] pointer on start function arguments. 124 66 * @ return 0 if success / return -1 if failure. 125 ***************************************************************************************** ***/67 *****************************************************************************************/ 126 68 int sys_thread_create( struct thread_s * new_thread, 127 69 struct pthread_attr_s * user_attr, … … 129 71 void * start_args ); 130 72 131 /****************************************************************************************** ***73 /****************************************************************************************** 132 74 * [3] This blocking function suspend execution of the calling thread until completion 133 75 * of another target thread identified by the <trdid> argument. 134 76 * If the <exit_value> argument is not NULL, the value passed to pthread_exit() by the 135 77 * target thread is stored in the location referenced by exit_value. 136 ****************************************************************************************** ***78 ****************************************************************************************** 137 79 * @ trdid : [in] target thread identifier. 138 80 * @ thread : [out] buffer for exit_value returned by target thread. 139 81 * @ return 0 if success / return -1 if failure. 140 ***************************************************************************************** ***/82 *****************************************************************************************/ 141 83 int sys_thread_join( trdid_t trdid, 142 84 void ** exit_value ); 143 85 144 /****************************************************************************************** ***86 /****************************************************************************************** 145 87 * [4] This function detach a joinable thread. 146 ****************************************************************************************** ***147 * @ trdid : thread identifier. 148 * @ return 0 if success / return -1 if failure. 149 ***************************************************************************************** ***/88 ****************************************************************************************** 89 * @ trdid : thread identifier.i 90 * @ return 0 if success / return -1 if failure. 91 *****************************************************************************************/ 150 92 int sys_thread_detach( trdid_t trdid ); 151 93 152 /********************************************************************************************* 153 * [5] This function calls the scheduler for the core running the calling thread. 154 ********************************************************************************************* 155 * @ return always 0. 156 ********************************************************************************************/ 157 int sys_thread_yield(); 158 159 /********************************************************************************************* 94 /****************************************************************************************** 95 * [5] This slot is not used. 96 *****************************************************************************************/ 97 98 /****************************************************************************************** 160 99 * [6] This function implement all operations on a POSIX unnamed semaphore, 161 100 * that can be shared by threads running in different clusters. 162 101 * The kernel structure representing a remote semaphore is in the remote_sem.h file, 163 102 * and the code implementing the operations is in the remore_sem.c file. 164 ****************************************************************************************** ***103 ****************************************************************************************** 165 104 * @ vaddr : semaphore virtual address in user space == identifier. 166 105 * @ operation : SEM_INIT / SEM_DESTROY / SEM_GETVALUE / SEM_POST / SEM_WAIT. 167 106 * @ value : pointer on in/out argument in user space. 168 107 * @ return 0 if success / return -1 if failure. 169 ***************************************************************************************** ***/108 *****************************************************************************************/ 170 109 int sys_sem( void * vaddr, 171 110 uint32_t operation, 172 111 uint32_t * value ); 173 112 174 typedef enum 175 { 176 SEM_INIT, 177 SEM_DESTROY, 178 SEM_GETVALUE, 179 SEM_WAIT, 180 SEM_POST, 181 } 182 sem_operation_t; 183 184 /********************************************************************************************* 113 /****************************************************************************************** 185 114 * [7] This function implement all operations on a POSIX condition variable. 186 115 * The kernel structure representing a cond_var is defined in the remote_cv.h file, 187 116 * The code implementing the operations is defined in the remote_cv.c file. 188 ****************************************************************************************** ***117 ****************************************************************************************** 189 118 * @ vaddr : condvar virtual address in user space == identifier. 190 119 * @ operation : operation type (see below). 191 120 * @ attr : mutex virtual address in user space == identifier. 192 121 * @ return 0 if success / return -1 if failure. 193 ***************************************************************************************** ***/122 *****************************************************************************************/ 194 123 int sys_condvar( void * condvar, 195 124 uint32_t operation, 196 125 void * mutex ); 197 126 198 typedef enum 199 { 200 CONDVAR_INIT, 201 CONDVAR_DESTROY, 202 CONDVAR_WAIT, 203 CONDVAR_SIGNAL, 204 CONDVAR_BROADCAST, 205 } 206 condvar_operation_t; 207 208 /********************************************************************************************* 127 /****************************************************************************************** 209 128 * [8] This function implement all operations on a POSIX barrier. 210 129 * The kernel structure representing a barrier is defined in the remote_barrier.h file. 211 130 * The code implementting the operations is defined in the remote_barrier.c file. 212 ****************************************************************************************** ***131 ****************************************************************************************** 213 132 * @ vaddr : barrier virtual address in user space == identifier. 214 133 * @ operation : BARRIER_INIT / BARRIER_DESTROY / BARRIER_WAIT. 215 134 * @ count : number of expected threads (only used by BARRIER_INIT operation). 216 135 * @ return 0 if success / return -1 if failure. 217 ***************************************************************************************** ***/136 *****************************************************************************************/ 218 137 int sys_barrier( void * vaddr, 219 138 uint32_t operation, 220 139 uint32_t count ); 221 140 222 typedef enum 223 { 224 BARRIER_INIT, 225 BARRIER_DESTROY, 226 BARRIER_WAIT, 227 } 228 barrier_operation_t; 229 230 /********************************************************************************************* 141 /****************************************************************************************** 231 142 * [9] This function implement all operations on a POSIX mutex. 232 143 * The kernel structure representing a barrier is defined in the remote_barrier.h file. 233 144 * The code implementting the operations is defined in the remote_barrier.c file. 234 ****************************************************************************************** ***145 ****************************************************************************************** 235 146 * @ vaddr : mutex virtual address in user space == identifier. 236 147 * @ operation : MUTEX_INIT / MUTEX_DESTROY / MUTEX_LOCK / MUTEX_UNLOCK 237 148 * @ attr : mutex attributes (non supported yet => must be 0). 238 149 * @ return 0 if success / return -1 if failure. 239 ***************************************************************************************** ***/150 *****************************************************************************************/ 240 151 int sys_mutex( void * vaddr, 241 152 uint32_t operation, 242 153 uint32_t count ); 243 154 244 typedef enum 245 { 246 MUTEX_INIT, 247 MUTEX_DESTROY, 248 MUTEX_LOCK, 249 MUTEX_UNLOCK, 250 } 251 mutex_operation_t; 252 253 /********************************************************************************************* 254 * [10] This function block the calling thread on the THREAD_BLOCKED_GLOBAL condition, 255 * and deschedule. 256 ********************************************************************************************* 257 * @ return 0 if success / returns -1 if failure. 258 ********************************************************************************************/ 259 int sys_thread_sleep(); 260 261 /********************************************************************************************* 262 * [11] This function unblock the thread identified by its <trdid> from the 263 * THREAD_BLOCKED_GLOBAL condition. 264 ********************************************************************************************* 265 * @ trdid : target thread identifier. 266 * @ return 0 if success / return -1 if failure. 267 ********************************************************************************************/ 268 int sys_thread_wakeup(); 269 270 /********************************************************************************************* 271 * [12] This function open or create a file. 272 ********************************************************************************************* 155 /****************************************************************************************** 156 * [10] This slot not allocated yet 157 ****************************************************************************************** 158 * @ return 0 if success / returns -1 if failure. 159 *****************************************************************************************/ 160 161 /****************************************************************************************** 162 * [11] This function rmove an existing mapping defined by the <addr> and <size> 163 * arguments in user space. 164 ****************************************************************************************** 165 * @ addr : base address in user space. 166 * # size : number of bytes. 167 * @ return 0 if success / return -1 if failure. 168 *****************************************************************************************/ 169 int sys_munmap( void * addr, 170 uint32_t size ); 171 172 /****************************************************************************************** 173 * [12] This function open or create an open file descriptor. 174 ****************************************************************************************** 273 175 * @ pathname : pathname (can be relative or absolute). 274 176 * @ flags : bit vector attributes (see below). 275 177 * @ mode : access rights. 276 178 * @ return file descriptor index in fd_array if success / return -1 if failure. 277 ***************************************************************************************** ***/179 *****************************************************************************************/ 278 180 int sys_open( char * pathname, 279 181 uint32_t flags, 280 182 uint32_t mode ); 281 183 282 typedef enum 283 { 284 O_RDONLY = 0x0010000, /*! open file in read-only mode */ 285 O_WRONLY = 0x0020000, /*! open file in write-only mode */ 286 O_RDWR = 0x0030000, /*! open file in read/write mode */ 287 O_NONBLOCK = 0x0040000, /*! do not block if data non available */ 288 O_APPEND = 0x0080000, /*! append on each write */ 289 O_CREAT = 0x0100000, /*! create file if it does not exist */ 290 O_TRUNC = 0x0200000, /*! file length is forced to 0 */ 291 O_EXCL = 0x0400000, /*! error if VFS_O_CREAT and file exist */ 292 O_SYNC = 0x0800000, /*! synchronize File System on each write */ 293 O_CLOEXEC = 0x1000000, /*! set the close-on-exec flag in file descriptor */ 294 O_DIR = 0x2000000, /*! new file descriptor is for a directory */ 295 } 296 open_attributes_t; 297 298 /********************************************************************************************* 299 * [13] This function creates a new file as specified by the arguments. 300 * This function is obsolete, you should use open() with 0_CREATE. 301 ********************************************************************************************* 302 * @ pathname : pathname (can be relative or absolute). 303 * @ mode : access rights. 304 ********************************************************************************************/ 305 int sys_creat( char * pathname, 306 uint32_t mode ); 307 308 /********************************************************************************************* 184 /****************************************************************************************** 185 * [13] This function map physical memory (or a file) in the calling thread virtual space. 186 * The <attr> argument is a pointer on a structure for arguments (see shared_syscalls.h). 187 ****************************************************************************************** 188 * @ attr : pointer on attributes structure. 189 * @ return 0 if success / return -1 if failure. 190 *****************************************************************************************/ 191 int sys_mmap( mmap_attr_t * attr ); 192 193 /****************************************************************************************** 309 194 * [14] This function read bytes from an open file identified by its file descriptor. 310 * Th isfile can be a regular file or character oriented device.311 ****************************************************************************************** ***195 * The file can be a regular file or character oriented device. 196 ****************************************************************************************** 312 197 * @ file_id : open file index in fd_array. 313 198 * @ buf : buffer virtual address in user space. 314 199 * @ count : number of bytes. 315 200 * @ return number of bytes actually read if success / returns -1 if failure. 316 ***************************************************************************************** ***/201 *****************************************************************************************/ 317 202 int sys_read( uint32_t file_id, 318 203 void * buf, 319 204 uint32_t count ); 320 205 321 /****************************************************************************************** ***206 /****************************************************************************************** 322 207 * [15] This function writes bytes to an open file identified by its file descriptor. 323 * Th isfile can be a regular file or character oriented device.324 ****************************************************************************************** ***208 * The file can be a regular file or character oriented device. 209 ****************************************************************************************** 325 210 * @ file_id : open file index in fd_array. 326 211 * @ buf : buffer virtual address in user space. 327 212 * @ count : number of bytes. 328 213 * @ return number of bytes actually written if success / returns -1 if failure. 329 ***************************************************************************************** ***/214 *****************************************************************************************/ 330 215 int sys_write( uint32_t file_id, 331 216 void * buf, 332 217 uint32_t count ); 333 218 334 /****************************************************************************************** ***335 * [16] This function epositions the offset of the file descriptor identified by <file_id>,336 * according to the operation type defined by the <whence> a nd <offset> arguments.337 ****************************************************************************************** ***219 /****************************************************************************************** 220 * [16] This function repositions the offset of the file descriptor identified by <file_id>, 221 * according to the operation type defined by the <whence> argument. 222 ****************************************************************************************** 338 223 * @ file_id : open file index in fd_array. 339 * @ offset : buffer virtual address in user space.224 * @ offset : used to compute new offset value. 340 225 * @ whence : operation type (see below). 341 226 * @ return 0 if success / returns -1 if failure. 342 ***************************************************************************************** ***/227 *****************************************************************************************/ 343 228 int sys_lseek( xptr_t file_id, 344 229 uint32_t offset, 345 230 uint32_t whence ); 346 231 347 typedef enum 348 { 349 SEEK_SET = 0, /*! new_offset <= offset */ 350 SEEK_CUR = 1, /*! new_offset <= current_offset + offset */ 351 SEEK_END = 2, /*! new_iffset <= current_size + offset */ 352 } 353 lseek_operation_t; 354 355 /********************************************************************************************* 232 /****************************************************************************************** 356 233 * [17] This function release the memory allocated for the file descriptor identified by 357 234 * the <file_id> argument, and remove the fd array_entry in all copies of the process 358 235 * descriptor. 359 ****************************************************************************************** ***236 ****************************************************************************************** 360 237 file_id : file descriptor index in fd_array. 361 238 * @ return 0 if success / returns -1 if failure. 362 ***************************************************************************************** ***/239 *****************************************************************************************/ 363 240 int sys_close( uint32_t file_id ); 364 241 365 /****************************************************************************************** ***366 * [18] This function removes a directory entry identified by the <pathname> from its242 /****************************************************************************************** 243 * [18] This function removes a directory entry identified by the <pathname> from the 367 244 * directory, and decrement the link count of the file referenced by the link. 368 245 * If the link count reduces to zero, and no process has the file open, then all resources … … 370 247 * the last link is removed, the link is removed, but the removal of the file is delayed 371 248 * until all references to it have been closed. 372 ****************************************************************************************** ***373 * @ pathname : pathname (can be relative or absolute). 374 * @ return 0 if success / returns -1 if failure. 375 ***************************************************************************************** ***/249 ****************************************************************************************** 250 * @ pathname : pathname (can be relative or absolute). 251 * @ return 0 if success / returns -1 if failure. 252 *****************************************************************************************/ 376 253 int sys_unlink( char * pathname ); 377 254 378 /****************************************************************************************** ***255 /****************************************************************************************** 379 256 * [19] This function creates in the calling thread cluster an unnamed pipe, and two 380 257 * (read and write) file descriptors. 381 ********************************************************************************************* 258 * TODO not implemented yet... 259 ****************************************************************************************** 382 260 * @ file_id[0] : [out] read only file descriptor index. 383 261 * @ file_id[1] : [out] write only file descriptor index. 384 262 * @ return 0 if success / return -1 if failure. 385 ***************************************************************************************** ***/263 *****************************************************************************************/ 386 264 int sys_pipe( uint32_t file_id[2] ); 387 265 388 /****************************************************************************************** ***266 /****************************************************************************************** 389 267 * [20] This function change the current working directory in reference process descriptor. 390 ****************************************************************************************** ***391 * @ pathname : pathname (can be relative or absolute). 392 * @ return 0 if success / returns -1 if failure. 393 ***************************************************************************************** ***/268 ****************************************************************************************** 269 * @ pathname : pathname (can be relative or absolute). 270 * @ return 0 if success / returns -1 if failure. 271 *****************************************************************************************/ 394 272 int sys_chdir( char * pathname ); 395 273 396 /****************************************************************************************** ***274 /****************************************************************************************** 397 275 * [21] This function creates a new directory in file system. 398 ****************************************************************************************** ***276 ****************************************************************************************** 399 277 * @ pathname : pathname (can be relative or absolute). 400 278 * @ mode : access rights (as defined in chmod). 401 279 * @ return 0 if success / returns -1 if failure. 402 ***************************************************************************************** ***/280 *****************************************************************************************/ 403 281 int sys_mkdir( char * pathname, 404 282 uint32_t mode ); 405 283 406 /****************************************************************************************** ***284 /****************************************************************************************** 407 285 * [22] This function creates a named FIFO file in the calling thread cluster. 408 286 * The associated read and write file descriptors mut be be explicitely created 409 * using the sy _open() function.410 ****************************************************************************************** ***287 * using the sys_open() function. 288 ****************************************************************************************** 411 289 * @ pathname : pathname (can be relative or absolute). 412 290 * @ mode : access rights (as defined in chmod). 413 291 * @ return 0 if success / returns -1 if failure. 414 ***************************************************************************************** ***/292 *****************************************************************************************/ 415 293 int sys_mkfifo( char * pathname, 416 294 uint32_t mode ); 417 295 418 /********************************************************************************************* 419 * [23] This function open a directory, that must exist in the file system. 420 ********************************************************************************************* 421 * @ pathname : pathname (can be relative or absolute). 422 * @ return file descriptor index in fd_array if success / return -1 if failure. 423 ********************************************************************************************/ 424 int sys_opendir( char * pathname ); 425 426 /********************************************************************************************* 427 * [24] This function returns in the structure pointed by the <dirent> argument various 428 * information about an entry of the directory identified by the <file_id> argument. 429 ********************************************************************************************* 430 * @ file_id : file descriptor index of the searched directory. 431 * @ dirent : pointer on a dirent structure in user space. 432 * @ return 0 if success / returns -1 if failure. 433 ********************************************************************************************/ 434 int sys_readdir( uint32_t file_id, 435 struct vfs_dirent_s * dirent ); 436 437 /********************************************************************************************* 438 * [25] This function close the file descriptor previouly open by the opendir() function. 439 ********************************************************************************************* 440 * @ file_id : file descriptor index of the searched directory. 441 * @ return 0 if success / returns -1 if failure. 442 ********************************************************************************************/ 443 int sys_closedir( uint32_t file_id ); 444 445 /********************************************************************************************* 296 /****************************************************************************************** 297 * [23] This function open a directory, that must exist in the file system, returning 298 * a DIR pointer on the directory in user space. 299 ****************************************************************************************** 300 * @ pathname : pathname (can be relative or absolute). 301 * @ dirp : [out] buffer for pointer on user directory (DIR). 302 * @ return 0 if success / returns -1 if failure. 303 *****************************************************************************************/ 304 int sys_opendir( char * pathname, 305 DIR ** dirp ); 306 307 /****************************************************************************************** 308 * [24] This function returns an user pointer on the dirent structure describing the 309 * next directory entry in the directory identified by the <dirp> argument. 310 ****************************************************************************************** 311 * @ dirp : user pointer identifying the searched directory. 312 * @ dentp : [out] buffer for pointer on user direntory entry (dirent). 313 * @ return O if success / returns -1 if failure. 314 *****************************************************************************************/ 315 int sys_readdir( DIR * dirp, 316 struct dirent ** dentp ); 317 318 /****************************************************************************************** 319 * [25] This function closes the directory identified by the <dirp> argument, and releases 320 * all structures associated with the <dirp> pointer. 321 ****************************************************************************************** 322 * @ dirp : user pointer identifying the directory. 323 * @ return 0 if success / returns -1 if failure. 324 *****************************************************************************************/ 325 int sys_closedir( DIR * dirp ); 326 327 /****************************************************************************************** 446 328 * [26] This function returns the pathname of the current working directory. 447 ****************************************************************************************** ***329 ****************************************************************************************** 448 330 * buf : buffer addres in user space. 449 331 * nbytes : user buffer size in bytes. 450 332 * @ return 0 if success / returns -1 if failure. 451 ***************************************************************************************** ***/333 *****************************************************************************************/ 452 334 int sys_getcwd( char * buf, 453 335 uint32_t nbytes ); 454 336 455 /********************************************************************************************* 456 * [27] This function returns in a 64 bits user buffer the calling core cycles count. 457 * It uses both the hardware register and the core descriptor cycles count tos take 458 * into account a possible harware register overflow in 32 bits architectures. 459 ********************************************************************************************* 460 * cyles : [out] address of buffer in user space. 461 ********************************************************************************************/ 462 int sys_clock( uint64_t * cycles ); 463 464 /********************************************************************************************* 337 /****************************************************************************************** 338 * [27] This slot is not used. 339 *****************************************************************************************/ 340 341 /****************************************************************************************** 465 342 * [28] This function forces the calling thread to sleep, for a fixed number of cycles. 466 ****************************************************************************************** ***343 ****************************************************************************************** 467 344 * cycles : number of cycles. 468 ***************************************************************************************** ***/345 *****************************************************************************************/ 469 346 int sys_alarm( uint32_t cycles ); 470 347 471 /********************************************************************************************* 472 * [29] This undefined function does nothing. 473 ********************************************************************************************* 474 * @ pathname : pathname (can be relative or absolute). 475 * @ return 0 if success / returns -1 if failure. 476 ********************************************************************************************/ 348 /****************************************************************************************** 349 * [29] This function removes a directory file whose name is given by <pathname>. 350 * The directory must not have any entries other than `.' and `..'. 351 ****************************************************************************************** 352 * @ pathname : pathname (can be relative or absolute). 353 * @ return 0 if success / returns -1 if failure. 354 *****************************************************************************************/ 477 355 int sys_rmdir( char * pathname ); 478 356 479 /****************************************************************************************** ***357 /****************************************************************************************** 480 358 * [30] This function implement the operations related to User Thread Local Storage. 481 359 * It is actually implemented as an uint32_t variable in the thread descriptor. 482 ****************************************************************************************** ***360 ****************************************************************************************** 483 361 * @ operation : UTLS operation type as defined below. 484 362 * @ value : argument value for the UTLS_SET operation. 485 363 * @ return value for the UTLS_GET and UTLS_GET_ERRNO / return -1 if failure. 486 ***************************************************************************************** ***/364 *****************************************************************************************/ 487 365 int sys_utls( uint32_t operation, 488 366 uint32_t value ); 489 367 490 typedef enum 491 { 492 UTLS_SET = 1, 493 UTLS_GET = 2, 494 UTLS_GET_ERRNO = 3, 495 } 496 utls_operation_t; 497 498 /********************************************************************************************* 368 /****************************************************************************************** 499 369 * [31] This function change the acces rights for the file/dir identified by the 500 370 * pathname argument. 501 ****************************************************************************************** ***371 ****************************************************************************************** 502 372 * @ pathname : pathname (can be relative or absolute). 503 373 * @ rights : acces rights. 504 374 * @ return 0 if success / returns -1 if failure. 505 ***************************************************************************************** ***/375 *****************************************************************************************/ 506 376 int sys_chmod( char * pathname, 507 377 uint32_t rights ); 508 378 509 /****************************************************************************************** ***379 /****************************************************************************************** 510 380 * [32] This function associate a specific signal handler to a given signal type. 511 381 * Tee handlers for the SIGKILL and SIGSTOP signals cannot be redefined. 512 ****************************************************************************************** ***382 ****************************************************************************************** 513 383 * @ sig_id : index defining signal type (from 1 to 31). 514 384 * @ handler : pointer on fonction implementing the specific handler. 515 385 * @ return 0 if success / returns -1 if failure. 516 ***************************************************************************************** ***/386 *****************************************************************************************/ 517 387 int sys_signal( uint32_t sig_id, 518 388 void * handler ); 519 389 520 /****************************************************************************************** ***390 /****************************************************************************************** 521 391 * [33] This function returns in the structure <tv>, defined in the time.h file, 522 392 * the current time (in seconds & micro-seconds). 523 393 * It is computed from the calling core descriptor. 524 394 * The timezone is not supported. 525 ****************************************************************************************** ***395 ****************************************************************************************** 526 396 * @ tv : pointer on the timeval structure. 527 397 * @ tz : pointer on the timezone structure : must be NULL. 528 398 * @ return 0 if success / returns -1 if failure. 529 ***************************************************************************************** ***/399 *****************************************************************************************/ 530 400 int sys_timeofday( struct timeval * tv, 531 401 struct timezone * tz ); 532 402 533 /****************************************************************************************** ***403 /****************************************************************************************** 534 404 * [34] This function implements the "kill" system call. 535 405 * It register the signal defined by the <sig_id> argument in all thread descriptors … … 537 407 * containing threads for the target process. 538 408 * It can be executed by any thread running in any cluster, as this function uses 539 * remote access to traverse the list of process copies in the owner cluster,409 * remote access to traverse the list of process copies stored in the owner cluster, 540 410 * and the RPC_SIGNAL_RISE to signal the remote threads. 541 ****************************************************************************************** ***411 ****************************************************************************************** 542 412 * @ pid : target process identifier. 543 413 * @ sig_id : index defining the signal type (from 1 to 31). 544 414 * @ return 0 if success / returns -1 if failure. 545 ***************************************************************************************** ***/415 *****************************************************************************************/ 546 416 int sys_kill( pid_t pid, 547 417 uint32_t sig_id ); 548 418 549 /****************************************************************************************** ***419 /****************************************************************************************** 550 420 * [35] This function implements the "getpid" system call. 551 ****************************************************************************************** ***552 * @ returns the PID for the calling thread.553 ***************************************************************************************** ***/421 ****************************************************************************************** 422 * @ returns the process PID for the calling thread. 423 *****************************************************************************************/ 554 424 int sys_getpid(); 555 425 556 /****************************************************************************************** ***426 /****************************************************************************************** 557 427 * [36] This function implement the "fork" system call. 558 428 * The calling process descriptor (parent process), and the associated thread descriptor are … … 560 430 * is registered in another target cluster, that is the new process owner. 561 431 * The child process and the associated main thread will be migrated to the target cluster 562 * later, when the child process makes an "exec" or any other system call. 432 * later, when the child process makes an "exec" or any other system call... TODO [AG] 563 433 * The target cluster depends on the "fork_user" flag and "fork_cxy" variable that can be 564 434 * stored in the calling thread descriptor by the specific fork_place() system call. 565 435 * If not, the sys_fork() function makes a query to the DQDT to select the target cluster. 566 ********************************************************************************************* 567 * @ returns child process PID if success / returns -1 if failure 568 ********************************************************************************************/ 436 ****************************************************************************************** 437 * @ if success, returns child process PID to parent, and return O to child. 438 * @ if failure, returns -1 to parent / no child process is created. 439 *****************************************************************************************/ 569 440 int sys_fork(); 570 441 571 /********************************************************************************************* 572 * [37] This function implement the "exec" system call. 573 * It is executed in the client cluster, but the new process descriptor and main thread 574 * must be created in a server cluster, that is generally another cluster. 575 * - if the server_cluster is the client cluster, call directly the process_make_exec() 442 /****************************************************************************************** 443 * [37] This function implement the "exec" system call, that creates a new process 444 * descriptor. 445 * It is executed in the client cluster, but the new process descriptor and the main 446 * thread are created in a server cluster, that is generally another cluster. 447 * - if the server_cluster is the client cluster, it calls directly the process_make_exec() 576 448 * function to create a new process, and launch a new thread in local cluster. 577 * - if the target_cluster is remote, call rpc_process_exec_client() to execute the578 * process_ make_exec() on the remote cluster.449 * - if the target_cluster is remote, it calls the rpc_process_exec_client() to execute 450 * process_signedmake_exec() on the remote cluster. 579 451 * In both case this function build an exec_info_t structure containing all informations 580 452 * required to build the new process descriptor and the associated thread. 581 453 * Finally, the calling process and thread are deleted. 582 ****************************************************************************************** ***583 * @ filename : string pointer on .elf filename ( virtualpointer in user space)584 * @ argv : array of strings on process arguments ( virtualpointers in user space)585 * @ envp : array of strings on Renvironment variables (virtualpointers in user space)454 ****************************************************************************************** 455 * @ filename : string pointer on .elf filename (pointer in user space) 456 * @ argv : array of strings on process arguments (pointers in user space) 457 * @ envp : array of strings on environment variables (pointers in user space) 586 458 * @ returns O if success / returns -1 if failure. 587 ***************************************************************************************** ***/459 *****************************************************************************************/ 588 460 int sys_exec( char * filename, 589 461 char ** argv, 590 462 char ** envp ); 591 463 592 /****************************************************************************************** ***593 * [38] This function returns in the <stat> structure, defined in the vfs.h file,594 * various informations on the file/directory identified by the <file_id> argument.595 ****************************************************************************************** ***596 * @ file_id : file descriptor index in fd_array.597 * @ stat : pointer on the stat structure.464 /****************************************************************************************** 465 * [38] This function returns in the <stat> structure, defined in the "shared_syscalls.h" 466 * file, various informations on the file/directory identified by the <pathname> argument. 467 ****************************************************************************************** 468 * @ pathname : user pointer on file pathname. 469 * @ stat : user pointer on the stat structure. 598 470 * @ returns O if success / returns -1 if failure. 599 ***************************************************************************************** ***/600 int sys_stat( uint32_t file_id,601 struct vfs_stat_s* stat );602 603 /****************************************************************************************** ***604 * [39] This function is used to activate / desactivate Rthe trace for a thread471 *****************************************************************************************/ 472 int sys_stat( const char * pathname, 473 struct stat * stat ); 474 475 /****************************************************************************************** 476 * [39] This non-standard function is used to activate / desactivate the trace for a thread 605 477 * identified by the <trdid> and <pid> arguments. 606 * It can be called by any other thread .607 ****************************************************************************************** ***478 * It can be called by any other thread in the same process. 479 ****************************************************************************************** 608 480 * @ operation : operation type as defined below. 609 481 * @ pid : process identifier. 610 482 * @ trdid : thread identifier. 611 483 * @ returns O if success / returns -1 if failure. 612 ***************************************************************************************** ***/484 *****************************************************************************************/ 613 485 int sys_trace( uint32_t operation, 614 486 pid_t pid, 615 487 uint32_t trdid ); 616 488 617 typedef enum 618 { 619 TRACE_ON = 0, 620 TRACE_OFF = 1, 621 } 622 trace_operation_t; 489 /****************************************************************************************** 490 * [40] This function returns the hardware platform parameters. 491 ****************************************************************************************** 492 * @ x_size : [out] number of clusters in a row. 493 * @ y_size : [out] number of clusters in a column. 494 * @ ncores : [out] number of cores per cluster. 495 * @ return 0 if success / return -1 if illegal arguments 496 *****************************************************************************************/ 497 int sys_get_config( uint32_t * x_size, 498 uint32_t * y_size, 499 uint32_t * ncores ); 500 501 /****************************************************************************************** 502 * [41] This function returns the calling core cluster and local index. 503 ****************************************************************************************** 504 * @ cxy : [out] cluster identifier (fixed format) 505 * @ lid : [out] core local index in cluster. 506 * @ return 0 if success / return -1 if illegal arguments 507 *****************************************************************************************/ 508 int sys_get_core( uint32_t * cxy, 509 uint32_t * lid ); 510 511 /****************************************************************************************** 512 * [42] This function returns in a 64 bits user buffer the calling core cycles count. 513 * It uses both the hardware register and the core descriptor cycles count to take 514 * into account a possible harware register overflow in 32 bits architectures. 515 ****************************************************************************************** 516 * cycle : [out] address of buffer in user space. 517 * @ return 0 if success / return -1 if illegal arguments 518 *****************************************************************************************/ 519 int sys_get_cycle( uint64_t * cycle ); 520 521 /****************************************************************************************** 522 * [43] This debug function displays on the kernel terminal the current state of a 523 * scheduler identified by the <cxy> and <lid> arguments. 524 ****************************************************************************************** 525 * cxy : [in] target cluster identifier. 526 * lid : [in] target core local index. 527 * @ return 0 if success / return -1 if illegal arguments 528 *****************************************************************************************/ 529 int sys_get_sched( uint32_t cxy, 530 uint32_t lid ); 531 532 /****************************************************************************************** 533 * [44] This debug function requires the kernel to display on the kernel terminal a message 534 * containing the thread / process / core identifiers, and the cause of panic, 535 * as defined by the <string> argument. 536 ****************************************************************************************** 537 * string : [in] message to be displayed. 538 * @ return always 0. 539 *****************************************************************************************/ 540 int sys_panic( char * string ); 541 542 /****************************************************************************************** 543 * [45] This function block the calling thread on the THREAD_BLOCKED_GLOBAL condition, 544 * and deschedule. 545 ****************************************************************************************** 546 * @ return 0 if success / returns -1 if failure. 547 *****************************************************************************************/ 548 int sys_thread_sleep(); 549 550 /****************************************************************************************** 551 * [46] This function unblock the thread identified by its <trdid> from the 552 * THREAD_BLOCKED_GLOBAL condition. 553 ****************************************************************************************** 554 * @ trdid : target thread identifier. 555 * @ return 0 if success / return -1 if failure. 556 *****************************************************************************************/ 557 int sys_thread_wakeup(); 623 558 624 559
Note: See TracChangeset
for help on using the changeset viewer.