- Timestamp:
- Apr 26, 2017, 2:11:56 PM (8 years ago)
- Location:
- trunk/kernel/kern
- Files:
-
- 2 added
- 2 deleted
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/blkio.c
r1 r5 26 26 #include <kmem.h> 27 27 #include <thread.h> 28 #include < device.h>28 #include <chdev.h> 29 29 #include <driver.h> 30 30 #include <event.h> -
trunk/kernel/kern/cluster.c
r1 r5 48 48 /////////////////////////////////////////////////////////////////////////////////////////// 49 49 50 process_t process_zero; 50 process_t process_zero; // allocated in kernel_init.c file 51 51 52 52 … … 78 78 cluster->cores_in_kernel = info->cores_nr; // all cpus start in kernel mode 79 79 80 // initialize kcm lock80 // initialize the lock protectig the embedded kcm allocator 81 81 spinlock_init( &cluster->kcm_lock ); 82 83 // initialize txt0 lock84 remote_spinlock_init( XPTR( local_cxy , &cluster->txt0_lock ) );85 82 86 83 // initialises DQDT … … 100 97 101 98 // initialises embedded KCM 102 kcm_init( &cluster->kcm , KMEM_KCM ); 103 104 // initialises cores99 kcm_init( &cluster->kcm , KMEM_KCM ); 100 101 // initialises all cores descriptors 105 102 for( lid = 0 ; lid < cluster->cores_nr; lid++ ) 106 103 { -
trunk/kernel/kern/cluster.h
r1 r5 98 98 spinlock_t kcm_lock; /*! local, protect creation of KCM allocators */ 99 99 remote_barrier_t barrier; /*! used to synchronize kernel parallel init */ 100 remote_spinlock_t txt0_lock; /*! global, only cluster_io lock is used */101 100 102 101 // global parameters … … 115 114 uint32_t cores_in_kernel; /*! number of cores currently in kernel mode */ 116 115 117 core_t core_tbl[CONFIG_MAX_ CORES_PER_CLUSTER]; /*! embedded cores*/116 core_t core_tbl[CONFIG_MAX_LOCAL_CORES]; /*! embedded cores */ 118 117 119 118 ppm_t ppm; /*! embedded kernel page manager */ … … 145 144 * This global variable is allocated in the kernel_init.c file. 146 145 * There is one cluster_manager per cluster, with the same local address, 147 * but different value, in all clusters containing a kernel instance.146 * but different content, in all clusters containing a kernel instance. 148 147 *****************************************************************************************/ 149 148 -
trunk/kernel/kern/core.c
r1 r5 30 30 #include <printk.h> 31 31 #include <thread.h> 32 #include <chdev.h> 32 33 #include <dev_icu.h> 33 34 #include <rpc.h> … … 41 42 ///////////////////////////////// 42 43 void core_init( core_t * core, 43 uint32_tlid,44 uint32_tgid )44 lid_t lid, 45 gid_t gid ) 45 46 { 46 47 core->lid = lid; … … 64 65 65 66 sched_init( core ); 66 67 core->icu = NULL; // TODO ??? [AG]68 67 } 69 68 … … 200 199 201 200 /////////////////////////////////////////////////// 202 void core_set_irq_vector_entry( xptr_t core_xp,201 void core_set_irq_vector_entry( core_t * core, 203 202 uint32_t irq_type, 204 203 uint32_t irq_id, 205 xptr_t dev_xp ) 206 { 207 // get core cluster and local pointer 208 cxy_t core_cxy = GET_CXY( core_xp ); 209 core_t * core_ptr = (core_t *)GET_PTR( core_xp ); 210 211 // compute xptr on relevant interrupt vector entry 212 xptr_t xp; 213 if ( irq_type == WTI_TYPE ) xp = XPTR( core_cxy , &core_ptr->wti_vector[irq_id] ); 214 else if( irq_type == HWI_TYPE ) xp = XPTR( core_cxy , &core_ptr->hwi_vector[irq_id] ); 215 else xp = XPTR( core_cxy , &core_ptr->pti_vector[irq_id] ); 216 217 // set relevant IRQ vector entry 218 hal_remote_swd( xp , dev_xp ); 219 } 204 chdev_t * chdev ) 205 { 206 if ( irq_type == WTI_TYPE ) core->wti_vector[irq_id] = chdev; 207 else if( irq_type == HWI_TYPE ) core->hwi_vector[irq_id] = chdev; 208 else core->pti_vector[irq_id] = chdev; 209 } -
trunk/kernel/kern/core.h
r1 r5 37 37 38 38 struct thread_s; 39 struct device_s;39 struct chdev_s; 40 40 41 41 42 42 /**************************************************************************************** 43 * This structure defines the core descriptor 43 * This structure defines the core descriptor. 44 * It contains the three interrupt vectors, that are implemented as array of pointers 45 * on the source channel devices, for all IRQs allocated to a given core. 44 46 ***************************************************************************************/ 45 47 … … 62 64 rpc_fifo_t rpc_fifo; /*! embedded private RPC fifo (one per core) */ 63 65 scheduler_t scheduler; /*! embedded private scheduler */ 64 struct device_s * icu; /*! pointer on local ICU device descriptor */65 66 66 xptr_thwi_vector[CONFIG_MAX_HWIS_PER_ICU]; /*! on source device */67 xptr_tpti_vector[CONFIG_MAX_PTIS_PER_ICU]; /*! on source device */68 xptr_twti_vector[CONFIG_MAX_WTIS_PER_ICU]; /*! on source device */67 struct chdev_s * hwi_vector[CONFIG_MAX_HWIS_PER_ICU]; /*! on source device */ 68 struct chdev_s * pti_vector[CONFIG_MAX_PTIS_PER_ICU]; /*! on source device */ 69 struct chdev_s * wti_vector[CONFIG_MAX_WTIS_PER_ICU]; /*! on source device */ 69 70 70 char name[CONFIG_SYSFS_NAME_LEN];71 71 sysfs_entry_t node; 72 72 } … … 159 159 * any thread in any cluster. 160 160 *************************************************************************************** 161 * @ core _xp : extendedpointer on the core descriptor.161 * @ core : local pointer on the core descriptor. 162 162 * @ irq_type : type of IRQ (HWI/WTI/PTI). 163 163 * @ irq_id : index in the IRQ vector. 164 * @ dev_xp : extended pointer on the "source"descriptor.164 * @ chdev : local pointer on the "source" chdev descriptor. 165 165 **************************************************************************************/ 166 void core_set_irq_vector_entry( xptr_t core_xp,167 uint32_t irq_type,168 uint32_t irq_id,169 xptr_t dev_xp);166 void core_set_irq_vector_entry( core_t * core, 167 uint32_t irq_type, 168 uint32_t irq_id, 169 struct chdev_s * chdev ); 170 170 171 171 -
trunk/kernel/kern/do_interrupt.c
r1 r5 25 25 #include <thread.h> 26 26 #include <cpu-trace.h> 27 #include < device.h>27 #include <chdev.h> 28 28 #include <system.h> 29 29 #include <signal.h> -
trunk/kernel/kern/dqdt.c
r1 r5 263 263 // analyse load for all children in non terminal node 264 264 load_min = 0xFFFFFFFF; 265 select = 0; 265 266 for( i = 0 ; i < 4 ; i++ ) 266 267 { -
trunk/kernel/kern/event.c
r1 r5 24 24 #include <cpu.h> 25 25 #include <cluster.h> 26 #include < device.h>26 #include <chdev.h> 27 27 #include <pmm.h> 28 28 #include <event.h> -
trunk/kernel/kern/kernel_init.c
r1 r5 40 40 #include <ppm.h> 41 41 #include <page.h> 42 #include < device.h>42 #include <chdev.h> 43 43 #include <boot_info.h> 44 44 #include <dqdt.h> 45 45 #include <dev_icu.h> 46 46 #include <dev_mmc.h> 47 #include <dev_ mwr.h>48 #include <dev_io x.h>47 #include <dev_dma.h> 48 #include <dev_iob.h> 49 49 #include <dev_ioc.h> 50 #include <dev_txt.h> 50 51 #include <dev_pic.h> 51 52 #include <printk.h> 52 53 #include <vfs.h> 53 54 55 #define KERNEL_INIT_SYNCRO 0xA5A5B5B5 54 #include <soclib_tty.h> 55 56 57 #define KERNEL_INIT_SYNCHRO 0xA5A5B5B5 56 58 57 59 /////////////////////////////////////////////////////////////////////////////////////////// … … 60 62 /////////////////////////////////////////////////////////////////////////////////////////// 61 63 64 // This variable defines the local boot_info structure 65 __attribute__((section(".kinfo"))) 66 boot_info_t boot_info CACHELINE_ALIGNED; 67 62 68 // This variable defines the local cluster manager 69 __attribute__((section(".kdata"))) 63 70 cluster_t cluster_manager CACHELINE_ALIGNED; 64 71 65 // This variable defines the kernel process descriptor and associated thread 72 // These variables define the kernel process0 descriptor and associated thread 73 __attribute__((section(".kdata"))) 66 74 process_t process_zero CACHELINE_ALIGNED; 67 75 thread_t thread_zero CACHELINE_ALIGNED; 68 76 69 77 // This variable contains the extended pointers on the device descriptors 70 devices_directory_t devices_dir CACHELINE_ALIGNED; 71 72 // This variable contains the input IRQ indexes for the PIC and ICU devices 73 devices_input_irq_t devices_input_irq CACHELINE_ALIGNED; 74 75 // This variable synchronizes the cores during kernel_init() 76 volatile uint32_t local_sync_init = 0; 78 __attribute__((section(".kdata"))) 79 chdev_directory_t chdev_dir CACHELINE_ALIGNED; 80 81 // This variable contains the input IRQ indexes for the PIC device 82 __attribute__((section(".kdata"))) 83 chdev_pic_input_t chdev_pic_input CACHELINE_ALIGNED; 84 85 // This variable contains the input IRQ indexes for the ICU device 86 __attribute__((section(".kdata"))) 87 chdev_icu_input_t chdev_icu_input CACHELINE_ALIGNED; 88 89 // This variable synchronizes the local cores during kernel_init() 90 __attribute__((section(".kdata"))) 91 volatile uint32_t local_sync_init CACHELINE_ALIGNED; 77 92 78 93 // This variable defines the local cluster identifier 79 cxy_t local_cxy; 80 81 82 /////////////////////////////////////////////////////////////////////////////////////////// 83 // This function displays the ALMOS_MKH.banner. 84 /////////////////////////////////////////////////////////////////////////////////////////// 85 static void print_boot_banner() 94 __attribute__((section(".kdata"))) 95 cxy_t local_cxy CACHELINE_ALIGNED; 96 97 // This variable is the lock protecting the kernel TXT terminal (used by printk) 98 __attribute__((section(".kdata"))) 99 remote_spinlock_t txt0_lock CACHELINE_ALIGNED; 100 101 /////////////////////////////////////////////////////////////////////////////////////////// 102 // This function displays the ALMOS_MKH banner. 103 /////////////////////////////////////////////////////////////////////////////////////////// 104 static void print_banner( uint32_t nclusters , uint32_t ncores ) 86 105 { 87 printk("\n ____ ___ ___ ___ _______ ________ ___ ___ ___ ___ \n"); 88 printk(" / \\ | | | \\ / | / ___ \\ / ____ | | \\ / | | | / / \n"); 89 printk(" / __ \\ | | | \\___/ | | / \\ | | / |_/ | \\___/ | | | / / \n"); 90 printk(" / / \\ \\ | | | _ _ | | | | | | |______ ___ | _ _ | | |__/ / \n"); 91 printk(" / /____\\ \\ | | | | \\ / | | | | | | \\______ \\ |___| | | \\ / | | | __ < \n"); 92 printk(" / ______ \\ | | _ | | \\_/ | | | | | | _ | | | | \\_/ | | | | \\ \\ \n"); 93 printk(" / / \\ \\ | |____/ | | | | | | \\___/ | | \\____/ | | | | | | | \\ \\\n"); 94 printk(" /_____/ \\_____\\|_________/|___| |___| \\_______/ |________/ |___| |___| |___| \\__\\\n"); 95 96 97 printk("\n\n\t\t\t\t Multi-Kernel Advanced Locality Management Operating System\n"); 98 printk("\t\t\t\t %s \n\n\n", CONFIG_ALMOS_VERSION ); 106 printk("\n" 107 " _ __ __ _____ ______ __ __ _ __ _ _ \n" 108 " /\\ | | | \\ / | / ___ \\ / _____| | \\ / | | | / / | | | | \n" 109 " / \\ | | | \\/ | | / \\ | | / | \\/ | | |/ / | | | | \n" 110 " / /\\ \\ | | | |\\ /| | | | | | | |_____ ___ | |\\ /| | | / | |___| | \n" 111 " / /__\\ \\ | | | | \\/ | | | | | | \\_____ \\ |___| | | \\/ | | | \\ | ___ | \n" 112 " / ______ \\ | | | | | | | | | | | | | | | | | |\\ \\ | | | | \n" 113 " / / \\ \\ | |____ | | | | | \\___/ | _____/ | | | | | | | \\ \\ | | | | \n" 114 " /_/ \\_\\ |______| |_| |_| \\_____/ |______/ |_| |_| |_| \\_\\ |_| |_| \n" 115 "\n\n\t\t Advanced Locality Management Operating System / Multi Kernel Hybrid\n" 116 "\n\n\t\t\t Version 0.0 : %d clusters / %d cores per cluster\n\n", nclusters , ncores ); 99 117 } 100 118 101 119 102 120 /////////////////////////////////////////////////////////////////////////////////////////// 103 // This static function allocates memory for all devices descriptors associated 104 // to peripherals contained in the local cluster: 105 // - the internal (replicated) devices are placed in the local cluster. 106 // - the external devices are pseudo-randomly distributed on all clusters. 107 // It initialises these device descriptors as specified by the boot_info_t structure, 108 // including the dynamic linking with the driver for the specified implementation. 109 // Finally, all copies of the devices directory are initialised. 110 // TODO check that cluster IO contains a PIC and IOB [AG] 121 // This static function allocates memory and initializes the TXT0 chdev descriptor, 122 // associated to the kernel terminal, shared by all kernel instances for debug messages. 123 // It should be called by a thread running in the I/O cluster, because the TXT0 chdev 124 // is created in the I/O cluster. 111 125 /////////////////////////////////////////////////////////////////////////////////////////// 112 126 // @ info : pointer on the local boot-info structure. 113 127 /////////////////////////////////////////////////////////////////////////////////////////// 114 static void devices_init( boot_info_t * info )128 static void txt0_device_init( boot_info_t * info ) 115 129 { 116 130 boot_device_t * dev_tbl; // pointer on array of devices in boot_info 117 131 uint32_t dev_nr; // actual number of devices in this cluster 118 xptr_t xp_dev; // extended pointer on device descriptor119 xptr_t xp_dev_bis; // extended pointer on second device descriptor120 132 xptr_t base; // remote pointer on segment base 121 133 uint32_t size; // channel size (bytes) … … 126 138 uint32_t x; // X cluster coordinate 127 139 uint32_t y; // Y cluster coordinate 128 uint32_t channels; // number of channels 129 uint32_t chl; // channel index 130 uint32_t p0; // device parameter 0 131 uint32_t p1; // device parameter 1 132 uint32_t p2; // device parameter 2 133 uint32_t p3; // device parameter 3 134 bool_t is_local; // true for internal peripherals 135 136 // get number of peripherals from boot_info 137 dev_nr = info->devices_nr; 138 dev_tbl = info->dev; 139 140 // loop on all peripherals in cluster 140 chdev_t * chdev; // local pointer on created chdev 141 142 // get number of peripherals and base of devices array from boot_info 143 dev_nr = info->ext_dev_nr; 144 dev_tbl = info->ext_dev; 145 146 // loop on external peripherals to find TXT 141 147 for( i = 0 ; i < dev_nr ; i++ ) 142 148 { 143 size = dev_tbl[i].size; 144 base = dev_tbl[i].base; 145 type = dev_tbl[i].type; 146 channels = dev_tbl[i].channels; 147 p0 = dev_tbl[i].param0; 148 p1 = dev_tbl[i].param1; 149 p2 = dev_tbl[i].param2; 150 p3 = dev_tbl[i].param3; 151 152 func = FUNC_FROM_TYPE( type ); 153 impl = IMPL_FROM_TYPE( type ); 154 155 // do nothing for RAM and ROM functional types 156 if( (type == DEV_FUNC_RAM) || (type == DEV_FUNC_ROM) ) continue; 157 158 // loop on channels in peripheral 159 for( chl = 0 ; chl < channels ; chl++ ) 160 { 161 // target cluster is local for internal (replicated) peripherals 162 if( (func == DEV_FUNC_ICU) || 163 (func == DEV_FUNC_MMC) || 164 (func == DEV_FUNC_MWR) ) is_local = true; 165 else is_local = false; 166 167 // allocate memory and initialize device descriptor 168 xp_dev = device_alloc( info , is_local ); 169 170 if( xp_dev == XPTR_NULL ) hal_core_sleep(); 171 172 device_init( xp_dev , 173 func , 174 impl, 175 chl, 176 false, // TX 177 base + size*chl, 178 size ); 179 180 // allocate memory and initialise another device descriptor if NIC, 181 // ALMOS-MKH uses two separate devices descriptor for NIC_RX and NIC_TX 182 if( func == DEV_FUNC_NIC ) 149 size = dev_tbl[i].size; 150 base = dev_tbl[i].base; 151 type = dev_tbl[i].type; 152 func = FUNC_FROM_TYPE( type ); 153 impl = IMPL_FROM_TYPE( type ); 154 155 if (func == DEV_FUNC_TXT ) 156 { 157 // allocate and initialize a local chdev for TXT0 158 chdev = chdev_create( func, 159 impl, 160 0, // channel 161 0, // direction 162 base ); 163 164 // Complete TXT specific initialisation 165 if( impl == IMPL_TXT_TTY ) 183 166 { 184 xp_dev_bis = device_alloc( info , is_local ); 185 186 if( xp_dev_bis == XPTR_NULL ) hal_core_sleep(); 187 188 device_init( xp_dev_bis , 189 func , 190 impl, 191 chl, 192 true, // RX 193 (base + size*chl), 194 size ); 195 } 196 197 // TODO ??? AG 198 // devfs_register( dev ); 199 200 // make device type specific initialisation 201 // the number of parameters depends on the device type 202 if ( func == DEV_FUNC_ICU ) dev_icu_init( xp_dev , p0 , p1 , p2 ); 203 else if( func == DEV_FUNC_MMC ) dev_mmc_init( xp_dev ); 204 // TODO else if( func == DEV_FUNC_MWR ) dev_mwr_init( xp_dev , p0 , p1 , p2 , p3 ); 205 else if( func == DEV_FUNC_IOB ) dev_iox_init( xp_dev ); 206 else if( func == DEV_FUNC_IOC ) dev_ioc_init( xp_dev ); 207 else if( func == DEV_FUNC_TXT ) dev_txt_init( xp_dev ); 208 else if( func == DEV_FUNC_PIC ) dev_pic_init( xp_dev , p0 ); 209 else if( func == DEV_FUNC_NIC ) dev_nic_init( xp_dev ); 210 else hal_core_sleep(); 211 212 // initialize the replicated devices_dir[x][y] structures 213 // defining the extended pointers on all devices descriptors 214 xptr_t * ptr_dev; 215 xptr_t * ptr_dev_bis; 216 217 if( func == DEV_FUNC_ICU ) ptr_dev = &devices_dir.icu[local_cxy]; 218 if( func == DEV_FUNC_MMC ) ptr_dev = &devices_dir.mmc[local_cxy]; 219 if( func == DEV_FUNC_MWR ) ptr_dev = &devices_dir.mwr[local_cxy]; 220 221 if( func == DEV_FUNC_TXT ) ptr_dev = &devices_dir.txt[chl]; 222 if( func == DEV_FUNC_IOB ) ptr_dev = &devices_dir.iob; 223 if( func == DEV_FUNC_IOC ) ptr_dev = &devices_dir.ioc; 224 if( func == DEV_FUNC_PIC ) ptr_dev = &devices_dir.pic; 225 if( func == DEV_FUNC_NIC ) ptr_dev = &devices_dir.nic_tx[chl]; 226 if( func == DEV_FUNC_NIC ) ptr_dev_bis = &devices_dir.nic_rx[chl]; 227 167 chdev->cmd = &soclib_tty_cmd; 168 chdev->isr = &soclib_tty_isr; 169 soclib_tty_init( chdev ); 170 } 171 172 // initialize the replicated chdev_dir[x][y] structures 228 173 for( x = 0 ; x < info->x_size ; x++ ) 229 174 { … … 231 176 { 232 177 cxy_t cxy = (x<<info->y_width) + y; 233 234 hal_remote_swd( XPTR( cxy , ptr_dev ) , xp_dev ); 235 236 if( func == DEV_FUNC_NIC ) 237 { 238 hal_remote_swd( XPTR( cxy , ptr_dev_bis ) , xp_dev_bis ); 178 hal_remote_swd( XPTR( cxy , &chdev_dir.txt[0] ) , XPTR( local_cxy , chdev ) ); 179 } 180 } 181 182 kinit_dmsg("\n[INFO] %s : core[%x][0] created TXT0 chdev / paddr = %l at cycle %d\n", 183 __FUNCTION__ , local_cxy , chdev_func_str( func ), chdev_xp , hal_time_stamp() ); 184 } 185 186 } // end loop on devices 187 188 } // end txt0_device_init() 189 190 /////////////////////////////////////////////////////////////////////////////////////////// 191 // This static function allocates memory for the chdev (channel_device) descriptors 192 // associated to the internal peripherals contained in the local cluster. These internal 193 // devices (ICU, MMC, DMA) chdev descriptors are placed in the local cluster. 194 // It initialises these device descriptors as specified by the boot_info_t structure, 195 // including the dynamic linking with the driver for the specified implementation. 196 // Finally, all copies of the devices directory are initialised. 197 /////////////////////////////////////////////////////////////////////////////////////////// 198 // @ info : pointer on the local boot-info structure. 199 /////////////////////////////////////////////////////////////////////////////////////////// 200 static void internal_devices_init( boot_info_t * info ) 201 { 202 boot_device_t * dev_tbl; // pointer on array of devices in boot_info 203 uint32_t dev_nr; // actual number of devices in this cluster 204 xptr_t base; // remote pointer on segment base 205 uint32_t size; // channel size (bytes) 206 uint32_t type; // peripheral type 207 uint32_t func; // device functionnal index 208 uint32_t impl; // device implementation index 209 uint32_t i; // device index in dev_tbl 210 uint32_t x; // X cluster coordinate 211 uint32_t y; // Y cluster coordinate 212 uint32_t channels_nr; // number of channels in device 213 uint32_t channel; // channel index 214 uint32_t p0; // device parameter 0 215 uint32_t p1; // device parameter 1 216 uint32_t p2; // device parameter 2 217 uint32_t p3; // device parameter 3 218 219 chdev_t * chdev; // local pointer on one channel_device descriptor 220 xptr_t chdev_xp; // extended pointer on channel_device descriptor 221 222 // get number of internal devices and base of devices array from boot_info 223 dev_nr = info->int_dev_nr; 224 dev_tbl = info->int_dev; 225 226 // loop on all internal devices in cluster 227 for( i = 0 ; i < dev_nr ; i++ ) 228 { 229 size = dev_tbl[i].size; 230 base = dev_tbl[i].base; 231 type = dev_tbl[i].type; 232 channels_nr = dev_tbl[i].channels; 233 p0 = dev_tbl[i].param0; 234 p1 = dev_tbl[i].param1; 235 p2 = dev_tbl[i].param2; 236 p3 = dev_tbl[i].param3; 237 238 func = FUNC_FROM_TYPE( type ); 239 impl = IMPL_FROM_TYPE( type ); 240 241 // do nothing for RAM, that does not require a chdev descriptor. 242 if( func == DEV_FUNC_RAM ) continue; 243 244 // check internal device functional type 245 if( (func != DEV_FUNC_MMC) && 246 (func != DEV_FUNC_ICU) && 247 (func != DEV_FUNC_DMA) ) 248 { 249 assert( false , __FUNCTION__ , "illegal internal peripheral type" ); 250 } 251 252 // loop on channels 253 for( channel = 0 ; channel < channels_nr ; channel++ ) 254 { 255 // create one chdev in local cluster 256 chdev = chdev_create( func , 257 impl, 258 channel, 259 false, // TX 260 base ); 261 262 assert( (chdev != NULL) , __FUNCTION__ , "cannot allocate internal chdev" ); 263 264 // get extended pointer on channel descriptor 265 chdev_xp = XPTR( local_cxy , chdev ); 266 267 // TODO ??? AG 268 // devfs_register( dev ); 269 270 // make device type specific initialisation 271 // the number of parameters depends on the device type 272 // TODO : remove these parameters that must be provided by the driver 273 if ( func == DEV_FUNC_ICU ) dev_icu_init( chdev , p0 , p1 , p2 ); 274 else if( func == DEV_FUNC_MMC ) dev_mmc_init( chdev ); 275 else dev_dma_init( chdev ); 276 277 // initialize the replicated chdev_dir[x][y] structures 278 // containing extended pointers on all devices descriptors 279 xptr_t * entry; 280 281 if ( func == DEV_FUNC_ICU ) entry = &chdev_dir.icu[local_cxy]; 282 else if( func == DEV_FUNC_MMC ) entry = &chdev_dir.mmc[local_cxy]; 283 else entry = &chdev_dir.dma[channel]; 284 285 if( func != DEV_FUNC_DMA ) // ICU and MMC devices are remotely accessible 286 { 287 for( x = 0 ; x < info->x_size ; x++ ) 288 { 289 for( y = 0 ; y < info->y_size ; y++ ) 290 { 291 cxy_t cxy = (x<<info->y_width) + y; 292 hal_remote_swd( XPTR( cxy , entry ) , chdev_xp ); 239 293 } 240 294 } 241 295 } 242 243 kinit_dmsg("[INFO] %s created device %s / channel %d / in cluster %x\n", 244 __FUNCTION__ , device_func_str[func] , chl , dev_cxy ); 296 else // DMA devices are NOT remotely accessible 297 { 298 *entry = chdev_xp; 299 } 300 301 kinit_dmsg("\n[INFO] %s :core[%x][0] created chdev %s / channel %d" 302 " / paddr = %l at cycle %d\n", 303 __FUNCTION__ , local_cxy , chdev_func_str( func ) , 304 channel , chdev_xp , hal_time_stamp() ); 245 305 246 306 } // end loop on channels 247 307 248 // initialize the replicated devices_irq[x][y] structures 249 // defining how peripherals are connected to PIC or ICU components 250 uint32_t id; 251 uint8_t valid; 252 uint32_t dev_type; 253 uint8_t channel; 254 uint8_t is_rx; 255 uint32_t * ptr_irq; 256 257 // default initiialization for devices_irq structure 258 259 // only external peripherals can be connected to PIC 308 // initialize the entries of the local chdev_icu_input structure 309 // defining how internal peripherals are connected to ICU 310 if( func == DEV_FUNC_ICU ) 311 { 312 uint32_t id; 313 uint8_t valid; 314 uint32_t dev_type; 315 uint8_t channel; 316 317 // loop on ICU inputs 318 for( id = 0 ; id < CONFIG_MAX_HWIS_PER_ICU ; id++ ) 319 { 320 valid = dev_tbl[i].irq[id].valid; 321 dev_type = dev_tbl[i].irq[id].dev_type; 322 channel = dev_tbl[i].irq[id].channel; 323 324 if( valid ) // only valid local IRQs are registered 325 { 326 uint32_t * index; // local pointer on the entry to be set 327 uint16_t dev_func = FUNC_FROM_TYPE( dev_type ); 328 if( dev_func == DEV_FUNC_MMC ) 329 index = &chdev_icu_input.mmc; 330 else if( dev_func == DEV_FUNC_DMA ) 331 index = &chdev_icu_input.dma[channel]; 332 else 333 { 334 assert( false , __FUNCTION__ , "illegal source device for ICU input" ); 335 } 336 337 // set entry in local structure 338 *index = id; 339 } 340 341 } // end loop on ICU inputs 342 } // end if ICU 343 } // end loop on peripherals 344 } // end internal_devices_init() 345 346 /////////////////////////////////////////////////////////////////////////////////////////// 347 // This static function allocates memory for the chdev descriptors associated 348 // to the external (shared) peripherals contained in the local cluster. These external 349 // devices (IOB, IOC, TXT, NIC, etc ) are distributed on all clusters. 350 // It initialises these device descriptors as specified by the boot_info_t structure, 351 // including the dynamic linking with the driver for the specified implementation. 352 // Finally, all copies of the devices directory are initialised. 353 // 354 // The number of channel_devices depends on the device functionnal type. 355 // There is three nested loops to scan the full set of external channel_devices: 356 // - loop on external devices. 357 // - loop on channels for multi-channels devices. 358 // - loop on directions (RX/TX) for NIC device. 359 // The set of channel_devices is indexed by the chdev_gid global index, that is used 360 // to select the cluster containing a given chdev[func,channel,direction]. 361 // All clusters scan the full set of chdevs, but only the cluster matching 362 // (chdev_gid % (x_size*y_size)) create the corresponding chdev. 363 // 364 // TODO check that cluster IO contains a PIC [AG] 365 /////////////////////////////////////////////////////////////////////////////////////////// 366 // @ info : pointer on the local boot-info structure. 367 /////////////////////////////////////////////////////////////////////////////////////////// 368 static void external_devices_init( boot_info_t * info ) 369 { 370 boot_device_t * dev_tbl; // pointer on array of devices in boot_info 371 uint32_t dev_nr; // actual number of devices in this cluster 372 xptr_t base; // remote pointer on segment base 373 uint32_t size; // channel size (bytes) 374 uint32_t type; // peripheral type 375 uint32_t func; // device functionnal index 376 uint32_t impl; // device implementation index 377 uint32_t i; // device index in dev_tbl 378 uint32_t x; // X cluster coordinate 379 uint32_t y; // Y cluster coordinate 380 uint32_t channels_nr; // number of channels 381 uint32_t channel; // channel index 382 uint32_t directions_nr; // number of directions 383 uint32_t direction; // direction index 384 uint32_t p0; // device parameter 0 385 uint32_t p1; // device parameter 1 386 uint32_t p2; // device parameter 2 387 uint32_t p3; // device parameter 3 388 uint32_t first_channel; // used in loop on channels 389 390 chdev_t * chdev; // local pointer on one channel_device descriptor 391 xptr_t chdev_xp; // extended pointer on channel_device descriptor 392 uint32_t chdev_gid = 0; // global index of channel_device descriptor 393 394 // get number of peripherals and base of devices array from boot_info 395 dev_nr = info->ext_dev_nr; 396 dev_tbl = info->ext_dev; 397 398 // loop on external peripherals 399 for( i = 0 ; i < dev_nr ; i++ ) 400 { 401 size = dev_tbl[i].size; 402 base = dev_tbl[i].base; 403 type = dev_tbl[i].type; 404 channels_nr = dev_tbl[i].channels; 405 p0 = dev_tbl[i].param0; 406 p1 = dev_tbl[i].param1; 407 p2 = dev_tbl[i].param2; 408 p3 = dev_tbl[i].param3; 409 410 func = FUNC_FROM_TYPE( type ); 411 impl = IMPL_FROM_TYPE( type ); 412 413 // There is one chdev per direction for NIC 414 if (func == DEV_FUNC_NIC) directions_nr = 2; 415 else directions_nr = 1; 416 417 // The TXT0 chdev has already been created 418 if (func == DEV_FUNC_TXT) first_channel = 1; 419 else first_channel = 0; 420 421 // do nothing for ROM, that does not require a device descriptor. 422 if( func == DEV_FUNC_ROM ) continue; 423 424 // check external device functionnal type 425 if( (func != DEV_FUNC_IOB) && 426 (func != DEV_FUNC_PIC) && 427 (func != DEV_FUNC_IOC) && 428 (func != DEV_FUNC_TXT) && 429 (func != DEV_FUNC_NIC) && 430 (func != DEV_FUNC_FBF) ) 431 { 432 assert( false , __FUNCTION__ , "undefined external peripheral type" ); 433 } 434 435 // loops on channels 436 for( channel = first_channel ; channel < channels_nr ; channel++ ) 437 { 438 // loop on directions 439 for( direction = 0 ; direction < directions_nr ; direction++ ) 440 { 441 // get target cluster for chdev[func,channel,direction] 442 uint32_t offset = chdev_gid % ( info->x_size * info->y_size ); 443 uint32_t cx = offset / info->y_size; 444 uint32_t cy = offset % info->y_size; 445 uint32_t target_cxy = (cx<<info->y_width) + cy; 446 447 // allocate and initialize a local chdev 448 // if local cluster matches target cluster 449 if( target_cxy == local_cxy ) 450 { 451 chdev = chdev_create( func, 452 impl, 453 channel, 454 direction, 455 base ); 456 457 assert( (chdev != NULL), __FUNCTION__ , 458 "cannot allocate external device" ); 459 460 // get extended pointer on chdev 461 chdev_xp = XPTR( local_cxy , chdev ); 462 463 // make device type specific initialisation 464 // the number of parameters depends on the device type 465 // TODO : remove the parameters that must be provided by the drivers 466 if ( func == DEV_FUNC_IOB ) dev_iob_init( chdev ); 467 else if( func == DEV_FUNC_IOC ) dev_ioc_init( chdev ); 468 else if( func == DEV_FUNC_TXT ) dev_txt_init( chdev ); 469 else if( func == DEV_FUNC_NIC ) dev_nic_init( chdev ); 470 else if( func == DEV_FUNC_PIC ) dev_pic_init( chdev , p0 ); 471 else if( func == DEV_FUNC_FBF ) dev_fbf_init( chdev , p0 , p1 ); 472 else 473 { 474 assert( false , __FUNCTION__ , "undefined device type" ); 475 } 476 477 // all external (shared) devices are remotely accessible 478 // initialize the replicated chdev_dir[x][y] structures 479 // defining the extended pointers on chdev descriptors 480 xptr_t * entry; 481 482 if( func == DEV_FUNC_IOB ) entry = &chdev_dir.iob; 483 if( func == DEV_FUNC_PIC ) entry = &chdev_dir.pic; 484 if( func == DEV_FUNC_TXT ) entry = &chdev_dir.txt[channel]; 485 if( func == DEV_FUNC_IOC ) entry = &chdev_dir.ioc[channel]; 486 if( func == DEV_FUNC_FBF ) entry = &chdev_dir.fbf[channel]; 487 if( func == DEV_FUNC_NIC ) entry = &chdev_dir.nic_tx[channel]; 488 489 for( x = 0 ; x < info->x_size ; x++ ) 490 { 491 for( y = 0 ; y < info->y_size ; y++ ) 492 { 493 cxy_t cxy = (x<<info->y_width) + y; 494 hal_remote_swd( XPTR( cxy , entry ) , chdev_xp ); 495 } 496 } 497 498 kinit_dmsg("\n[INFO] %s : core[%x][0] created chdev %s / channel = %d" 499 " / paddr = %l at cycle %d\n", 500 __FUNCTION__ , local_cxy , chdev_func_str( func ), 501 channel , chdev_xp , hal_time_stamp() ); 502 503 } // end if match 504 505 // increment chdev global index (matching or not) 506 chdev_gid++; 507 508 } // end loop on directions 509 510 } // end loop on channels 511 512 // initialize the entries of the local chdev_pic_input structure 513 // defining how external peripherals are connected to PIC 260 514 if( func == DEV_FUNC_PIC ) 261 515 { 516 uint32_t id; 517 uint8_t valid; 518 uint32_t dev_type; 519 uint8_t channel; 520 uint8_t is_rx; 521 262 522 // loop on PIC inputs 263 523 for( id = 0 ; id < CONFIG_MAX_IRQS_PER_PIC ; id++ ) … … 268 528 is_rx = dev_tbl[i].irq[id].is_rx; 269 529 270 // only valid IRQs are registered in the devices_input_irq structure 271 // ptr_irq is a local pointer on the entry to be set in devices_irq 272 if( valid ) 530 if( valid ) // only valid inputs are registered 273 531 { 532 uint32_t * index; // local pointer on one entry 274 533 uint16_t dev_func = FUNC_FROM_TYPE( dev_type ); 275 if( dev_func == DEV_FUNC_TXT ) 276 ptr_irq = &devices_input_irq.txt[channel]; 277 if( dev_func == DEV_FUNC_IOC ) 278 ptr_irq = &devices_input_irq.ioc; 279 if( (dev_func == DEV_FUNC_NIC) && (is_rx == 0) ) 280 ptr_irq = &devices_input_irq.nic_tx[channel]; 281 if( (dev_func == DEV_FUNC_NIC) && (is_rx != 0) ) 282 ptr_irq = &devices_input_irq.nic_rx[channel]; 283 284 // all copies of devices_irq must be updated in all clusters 285 for( x = 0 ; x < info->x_size ; x++ ) 286 { 287 for( y = 0 ; y < info->y_size ; y++ ) 288 { 289 cxy_t cxy = (x<<info->y_width) + y; 290 hal_remote_sw( XPTR( cxy , ptr_irq ) , id ); 291 } 534 535 if( dev_func == DEV_FUNC_TXT ) 536 { 537 index = &chdev_pic_input.txt[channel]; 292 538 } 539 else if( dev_func == DEV_FUNC_IOC ) 540 { 541 index = &chdev_pic_input.ioc[channel]; 542 } 543 else if( (dev_func == DEV_FUNC_NIC) && (is_rx == 0) ) 544 { 545 index = &chdev_pic_input.nic_tx[channel]; 546 } 547 else if( (dev_func == DEV_FUNC_NIC) && (is_rx != 0) ) 548 { 549 index = &chdev_pic_input.nic_rx[channel]; 550 } 551 else 552 { 553 assert( false , __FUNCTION__ , "illegal source device for PIC input" ); 554 } 555 556 // set entry in local structure 557 *index = id; 293 558 } 294 559 } // end loop on PIC inputs 295 560 } // end PIC 296 297 // only internal peripherals can be connected to ICU 298 if( func == DEV_FUNC_ICU ) 299 { 300 // loop on ICU inputs 301 for( id = 0 ; id < CONFIG_MAX_HWIS_PER_ICU ; id++ ) 302 { 303 valid = dev_tbl[i].irq[id].valid; 304 dev_type = dev_tbl[i].irq[id].dev_type; 305 channel = dev_tbl[i].irq[id].channel; 306 307 // only valid IRQs are registered in the devices_input_irq structure 308 // ptr_irq is a local pointer on the entry to be set in devices_irq 309 if( valid ) 310 { 311 uint16_t dev_func = FUNC_FROM_TYPE( dev_type ); 312 if( dev_func == DEV_FUNC_MMC ) 313 ptr_irq = &devices_input_irq.mmc[local_cxy]; 314 if( dev_func == DEV_FUNC_MWR ) 315 ptr_irq = &devices_input_irq.mwr[local_cxy]; 316 317 // all copies of devices_irq must be updated in all clusters 318 for( x = 0 ; x < info->x_size ; x++ ) 319 { 320 for( y = 0 ; y < info->y_size ; y++ ) 321 { 322 cxy_t cxy = (x<<info->y_width) + y; 323 hal_remote_sw( XPTR( cxy , ptr_irq ) , id ); 324 } 325 } 326 } 327 } // end loop on ICU inputs 328 } // end ICU 329 } // end loop on peripherals 330 } // end devices_init() 331 561 } // end loop on devices 562 } // end external_devices_init() 332 563 333 564 … … 335 566 // This function is the entry point for the kernel initialisation. 336 567 // It is executed by all cores in all clusters, but only core[0] in each cluster 337 // initialize the cluster manager, ant the other local shared resources. 338 // To comply with the multi-kernels paradigm, it access only local cluster memory, 339 // using only informations contained in the local boot_info_t structure, 340 // that has been set by the bootloader. 341 // All cores TODO ... 568 // initialize the cluster manager, ant the local peripherals. 569 // To comply with the multi-kernels paradigm, it access only local cluster memory, using 570 // only informations contained in the local boot_info_t structure, set by the bootloader. 342 571 /////////////////////////////////////////////////////////////////////////////////////////// 343 572 // @ info : pointer on the local boot-info structure. … … 363 592 364 593 // Each core makes an associative search in boot_info 365 // to get its (cxy,lid) composite index 594 // to get its (cxy,lid) composite index from its gid 366 595 found = false; 367 596 core_cxy = 0; … … 378 607 } 379 608 380 if ( found == false ) 381 { 382 printk("PANIC in %s : Core %d not registered in cluster %x\n", 383 __FUNCTION__ , core_gid , local_cxy ); 384 hal_core_sleep(); 385 } 386 387 if ( core_cxy != local_cxy) 388 { 389 printk("PANIC in %s : Core %d has wrong cxy in cluster %x\n", 390 __FUNCTION__ , core_gid , local_cxy ); 391 hal_core_sleep(); 392 } 393 394 // from this point, only core[0] initialises local resources 609 // suicide if not found 610 if( (found == false) || (core_cxy != local_cxy) ) hal_core_sleep(); 611 612 ////////////////////////////////////////////////////////////// 613 // In first step, only CP0 initialises local resources 614 ////////////////////////////////////////////////////////////// 615 395 616 if( core_lid == 0 ) 396 617 { 397 618 // initialize local cluster manager (cores and memory allocators) 398 619 error = cluster_init( info ); 399 if ( error == 0 ) 400 { 401 printk("PANIC in %s : Failed to initialize cluster manager in cluster %x\n", 402 __FUNCTION__ , local_cxy ); 403 hal_core_sleep(); 404 } 620 621 // suicide if failure 622 if( error ) hal_core_sleep(); 623 624 // get pointer on local cluster manager and on core descriptor 625 cluster = LOCAL_CLUSTER; 626 core = &cluster->core_tbl[core_lid]; 405 627 406 628 // initialize process_zero descriptor 407 629 process_zero_init( info ); 408 630 409 // initialize thread_zero descriptor631 // CP0 initialize its private thread_zero descriptor 410 632 memset( &thread_zero , 0 , sizeof(thread_t) ); 411 633 thread_zero.type = THREAD_KERNEL; … … 413 635 hal_set_current_thread( &thread_zero ); 414 636 415 // initialise local devices descriptors 416 devices_init( info ); 637 // CP0 in I/O cluster initialize the kernel TXT0 chdev descriptor. 638 // this TXTO device is shared by the all kernel instances for debug messages: 639 // the printk() function call the dev_txt_sync_write() function that call 640 // directly the relevant TXT driver, without desheduling. 641 if( core_cxy == info->io_cxy ) txt0_device_init( info ); 642 643 // synchronise all CP0s before using TXT0 644 remote_barrier( XPTR( info->io_cxy , &cluster->barrier ) , 645 (cluster->x_size * cluster->y_size) ); 646 647 // All CP0 initialise internal peripheral chdev descriptors. 648 // Each CP0[cxy] scan the set of its internal (private) peripherals, 649 // and allocate memory for the corresponding chdev descriptors. 650 internal_devices_init( info ); 651 652 // All CP0 contribute to initialise external peripheral chdev descriptors. 653 // Each CP0[cxy] scan the set of external (shared) peripherals (but the TXT0), 654 // and allocates memory for the chdev descriptors that must be placed 655 // on the (cxy) cluster according to its global index. 656 external_devices_init( info ); 417 657 418 658 // TODO initialize devFS and sysFS … … 420 660 // sysfs_root_init(); 421 661 422 // TODO dire précisément ce qu'on fait ici [AG]423 // hal_arch_init( info );424 425 662 // TODO ??? [AG] 426 663 // clusters_sysfs_register(); 427 664 428 // initialize virtual file system665 // TODO initialize virtual file system 429 666 // vfs_init(); 430 667 … … 433 670 434 671 // activate other cores in same cluster 435 local_sync_init = KERNEL_INIT_SYNC RO;672 local_sync_init = KERNEL_INIT_SYNCHRO; 436 673 hal_wbflush(); 437 674 } … … 439 676 { 440 677 // other cores wait synchro from core[0] 441 while( local_sync_init != KERNEL_INIT_SYNC RO )678 while( local_sync_init != KERNEL_INIT_SYNCHRO ) 442 679 { 443 680 uint32_t retval = hal_time_stamp() + 1000; … … 445 682 } 446 683 447 // other cores initialise thread_zero descriptor 684 // get pointer on local cluster manager and on core descriptor 685 cluster = LOCAL_CLUSTER; 686 core = &cluster->core_tbl[core_lid]; 687 688 // core initialise its private thread_zero descriptor 448 689 memset( &thread_zero , 0 , sizeof(thread_t) ); 449 690 thread_zero.type = THREAD_KERNEL; … … 451 692 hal_set_current_thread( &thread_zero ); 452 693 } 453 454 455 // each core get pointer on local cluster manager and on core descriptor456 cluster = LOCAL_CLUSTER;457 core = &cluster->core_tbl[core_lid];458 694 459 695 // each core creates its private idle thread descriptor … … 463 699 NULL, 464 700 core_lid ); 465 if( error ) 466 { 467 printk("ERROR in %s: failed to create idle thread for core %d in cluster %x\n", 468 __FUNCTION__ , core_lid , core_cxy ); 469 hal_core_sleep(); 470 } 701 702 assert( (error == 0) , __FUNCTION__ , "cannot create idle thread" ); 471 703 472 704 // each core register thread_idle in scheduler … … 476 708 hal_set_current_thread( thread_idle ); 477 709 478 kinit_dmsg(" INFO %s Created thread idle %x for core %d at cycle %d ]\n",479 thread, hal_get_gid(), hal_time_stamp());710 kinit_dmsg("\n[INFO] %s : thread idle created for core[%x][%d] at cycle %d\n", 711 __FUNCTION__ , core_cxy , core_lid , hal_time_stamp()); 480 712 481 713 // global syncho for all core[0] in all clusters … … 490 722 cluster->cores_nr ); 491 723 492 if( core_lid == 0 )724 if( (core_lid == 0) && (local_cxy == info->io_cxy) ) 493 725 { 494 kinit_dmsg("INFO %s completed for cluster %x at cycle %d\n", 495 __FUNCTION__ , local_cxy , hal_time_stamp() ); 496 497 if( local_cxy == info->io_cxy ) print_boot_banner(); 726 print_banner( (info->x_size * info->y_size) , info->cores_nr ); 498 727 } 499 728 500 // load idle thread context in calling core729 // load idle thread context on calling core 501 730 hal_cpu_context_load( thread_idle ); 502 731 -
trunk/kernel/kern/printk.c
r1 r5 24 24 #include <hal_types.h> 25 25 #include <hal_irqmask.h> 26 #include <printk.h> 27 #include <stdarg.h> 26 #include <hal_special.h> 28 27 #include <dev_txt.h> 29 28 #include <remote_spinlock.h> 30 29 #include <cluster.h> 30 #include <printk.h> 31 31 32 32 /////////////////////////////////////////////////////////////////////////////////// 33 // This static function is called by printk(), nolock_printk() and user_printk() 33 // This static function is called by kernel_printf() to display a string on the 34 // TXT channel defined by the <channel> argument. 35 // The access mode is defined by the <busy> argument: 36 // - if <busy> is true, it uses the dev_txt_sync_write() function, that takes the 37 // TXT lock, and call directly the relevant TXT driver, without descheduling. 38 // - if <busy is false, it uses the dev_txt_write() function, that register the 39 // write buffer in the relevant TXT chdev queue, and uses a descheduling policy. 34 40 /////////////////////////////////////////////////////////////////////////////////// 41 // @ channel : TXT channel. 42 // @ busy : TXT device acces mode. 43 // @ buf : buffer containing the characters. 44 // @ nc : number of characters. 45 // return 0 if success / return -1 if TTY0 busy after 10000 retries. 46 /////////////////////////////////////////////////////////////////////////////////// 47 static error_t txt_write( uint32_t channel, 48 uint32_t busy, 49 char * buffer, 50 uint32_t count ) 51 { 52 if( busy ) return dev_txt_sync_write( channel , buffer , count ); 53 else return dev_txt_write( channel , buffer , count ); 54 } 55 56 ////////////////////////////////////////////////////////////////////////////////////// 57 // This static function is called by printk() and user_printk() to build 58 // a formated string. 59 ////////////////////////////////////////////////////////////////////////////////////// 60 // @ channel : channel index. 61 // @ busy : TXT device access mode. 62 // @ format : printf like format. 63 // @ args : format arguments. 64 ////////////////////////////////////////////////////////////////////////////////////// 35 65 static void kernel_printf( uint32_t channel, 66 uint32_t busy, 36 67 char * format, 37 68 va_list * args ) … … 46 77 if (i) 47 78 { 48 dev_txt_sync_write( channel, format, i );79 txt_write( channel, busy, format, i ); 49 80 format += i; 50 81 } … … 83 114 { 84 115 val = -val; 85 dev_txt_sync_write( channel, "-" , 1 );116 txt_write( channel, busy, "-" , 1 ); 86 117 } 87 118 for(i = 0; i < 10; i++) … … 109 140 { 110 141 uint32_t val = va_arg( *args , uint32_t ); 111 dev_txt_sync_write( channel, "0x" , 2 );142 txt_write( channel, busy, "0x" , 2 ); 112 143 for(i = 0; i < 8; i++) 113 144 { 114 buf[7 - i] = HexaTab[val % 16];145 buf[7 - i] = HexaTab[val & 0xF]; 115 146 if (!(val = (val>>4))) break; 116 147 } … … 119 150 break; 120 151 } 121 case ('X'): /* 32 bits hexadecimal unsigned on 10 char */152 case ('X'): /* 32 bits hexadecimal unsigned on 10 char */ 122 153 { 123 154 uint32_t val = va_arg( *args , uint32_t ); 124 dev_txt_sync_write( channel, "0x" , 2 );155 txt_write( channel, busy, "0x" , 2 ); 125 156 for(i = 0; i < 8; i++) 126 157 { 127 buf[7 - i] = HexaTab[val % 16];158 buf[7 - i] = HexaTab[val & 0xF]; 128 159 val = (val>>4); 129 160 } … … 135 166 { 136 167 uint64_t val = va_arg( *args , uint64_t ); 137 dev_txt_sync_write( channel, "0x" , 2 );168 txt_write( channel, busy, "0x" , 2 ); 138 169 for(i = 0; i < 16; i++) 139 170 { 140 buf[15 - i] = HexaTab[val % 16];141 if (!(val /= 16)) break;171 buf[15 - i] = HexaTab[val & 0xF]; 172 if (!(val = (val>>4))) break; 142 173 } 143 174 len = i + 1; 144 175 pbuf = &buf[15 - i]; 176 break; 177 } 178 case ('L'): /* 64 bits hexadecimal unsigned on 18 char */ 179 { 180 uint64_t val = va_arg( *args , uint64_t ); 181 txt_write( channel, busy, "0x" , 2 ); 182 for(i = 0; i < 16; i++) 183 { 184 buf[15 - i] = HexaTab[val & 0xF]; 185 val = (val>>4); 186 } 187 len = 16; 188 pbuf = buf; 145 189 break; 146 190 } … … 157 201 default: 158 202 { 159 dev_txt_sync_write( channel,160 203 txt_write( channel , busy, 204 "\n[PANIC] in kernel_printf() : illegal format\n", 45 ); 161 205 } 162 206 } 163 207 164 if( pbuf != NULL ) dev_txt_sync_write( channel, pbuf, len );208 if( pbuf != NULL ) txt_write( channel, busy, pbuf, len ); 165 209 166 210 goto printf_text; … … 169 213 } // end kernel_printf() 170 214 171 //////////////////////////////// ///////172 void nolock_printk( char* format, ...)173 { 174 va_list args;215 //////////////////////////////// 216 void printk( char * format, ...) 217 { 218 va_list args; 175 219 176 220 // call kernel_printf 177 221 va_start( args , format ); 178 kernel_printf( 0 , format , &args );222 kernel_printf( 0 , 1 , format , &args ); 179 223 va_end( args ); 180 224 } 181 225 182 //////////////////////////////// 183 void printk( char* format, ...) 184 { 185 va_list args; 186 uint32_t save_sr; 187 188 // disable IRQs 189 hal_disable_irq( &save_sr ); 190 191 // get TXT0 lock 192 cluster_t * cluster = LOCAL_CLUSTER; 193 remote_spinlock_lock( XPTR( cluster->io_cxy , &cluster->txt0_lock ) ); 226 ///////////////////////////////////// 227 void user_printk( char* format, ...) 228 { 229 va_list args; 230 231 // get calling thread TXT channel TODO 232 uint32_t channel = 0; 194 233 195 234 // call kernel_printf 196 235 va_start( args , format ); 197 kernel_printf( 0, format , &args ); 198 va_end( args ); 199 200 // release TXT0 lock 201 remote_spinlock_unlock( XPTR( cluster->io_cxy , &cluster->txt0_lock ) ); 202 203 // restore IRQs 204 hal_restore_irq( save_sr ); 205 } 206 207 ///////////////////////////////////// 208 void user_printk( char* format, ...) 209 { 210 va_list args; 211 212 // get calling thread TXT channel TODO 213 uint32_t channel = 0; 214 215 // call kernel_printf 216 va_start( args , format ); 217 kernel_printf( channel, format , &args ); 236 kernel_printf( channel, 0 , format , &args ); 218 237 va_end( args ); 219 238 } 220 239 221 240 /////////////////////////////////////////// 241 inline void assert( bool_t condition, 242 const char * function_name, 243 char * string ) 244 { 245 if( condition == false ) 246 { 247 printk("\n[PANIC] in %s : %s\n" , function_name , string ); 248 hal_core_sleep(); 249 } 250 } 222 251 223 252 // Local Variables: -
trunk/kernel/kern/printk.h
r1 r5 24 24 /////////////////////////////////////////////////////////////////////////////////// 25 25 // The printk.c and printk.h files define the functions used by the kernel 26 // to display messages on the kernel text terminal, using a busy waiting 27 // policy if required : these functions does not use the TXT kernel thread, 28 // and does not deschedule if TXT peripheral is not available. 29 // These functions use the generic TXT device to call the proper implementation 26 // to display messages on a text terminal. 27 // Two access modes are supported: 28 // - The printk() function displays kernel messages on the kernel terminal TXT0, 29 // using a busy waiting policy: It calls directly the relevant TXT driver, 30 // after taking the TXT0 chdev lock for exclusive access to the TXT0 terminal. 31 // - The user_printk() function displays messages on the calling thread private 32 // terminal, using a descheduling policy: it register the request in the selected 33 // TXT chdev waiting queue and deschedule. The calling thread is reactivated by 34 // the IRQ signaling completion. 35 // Both functions use the generic TXT device to call the proper implementation 30 36 // dependant TXT driver. 37 // Finally these files define a set of conditionnal trace <***_dmsg> for debug. 31 38 /////////////////////////////////////////////////////////////////////////////////// 32 39 … … 34 41 #define _PRINTK_H 35 42 36 /////////////////////////////////////////////////////////////////////////////////// 37 // Access functions to kernel terminal TTY0 38 /////////////////////////////////////////////////////////////////////////////////// 39 43 #include <hal_types.h> 44 #include <stdarg.h> 45 46 47 /********************************************************************************** 48 * This function displays a formated string on the kernel terminal TXT0, 49 * using a busy waiting policy: It calls directly the relevant TXT driver, 50 * after taking the TXT0 chdev lock for exclusive access to the TXT0 terminal. 51 ********************************************************************************** 52 * @ format : formated string. 53 *********************************************************************************/ 40 54 extern void printk( char* format, ... ); 41 55 42 extern void nolock_printk( char* format, ... ); 43 56 /********************************************************************************** 57 * Display a formated string on the calling thread private terminal, using a 58 * descheduling policy: it register the request in the selected TXT chdev waiting 59 * queue and deschedule. IT is reactivated by the IRQ signaling completion. 60 * Not fully implemented yet ( use TXT0 in deschedling mode ). 61 ********************************************************************************** 62 * @ format : formated string. 63 *********************************************************************************/ 44 64 extern void user_printk( char* format, ... ); 45 65 66 /********************************************************************************** 67 * This function displaya "PANIC" message and force the calling core in 68 * sleeping mode if a Boolean condition is false. 69 * These functions are actually used to debug the kernel... 70 ********************************************************************************** 71 * @ condition : condition that must be true. 72 * @ function_name : name of the calling function. 73 * @ string : error message if condition is false. 74 *********************************************************************************/ 75 inline void assert( bool_t condition, 76 const char * function_name, 77 char * string ); 78 46 79 /////////////////////////////////////////////////////////////////////////////////// 47 80 // Conditionnal debug macros 48 81 /////////////////////////////////////////////////////////////////////////////////// 49 82 83 #if CONFIG_CONTEXT_DEBUG 84 #define context_dmsg(...) printk(__VA_ARGS__) 85 #else 86 #define context_dmsg(...) 87 #endif 88 50 89 #if CONFIG_CORE_DEBUG 51 #define core_dmsg(...) printk(__VA_ _ARGS__)90 #define core_dmsg(...) printk(__VA_ARGS__) 52 91 #else 53 92 #define core_dmsg(...) … … 55 94 56 95 #if CONFIG_DQDT_DEBUG 57 #define dqdt_dmsg(...) printk(__VA__ARGS__) 96 #define dma_dmsg(...) printk(__VA_ARGS__) 97 #else 98 #define dma_dmsg(...) 99 #endif 100 101 #if CONFIG_DQDT_DEBUG 102 #define dqdt_dmsg(...) printk(__VA_ARGS__) 58 103 #else 59 104 #define dqdt_dmsg(...) … … 61 106 62 107 #if CONFIG_ELF_DEBUG 63 #define elf_dmsg(...) printk(__VA_ _ARGS__)108 #define elf_dmsg(...) printk(__VA_ARGS__) 64 109 #else 65 110 #define elf_dmsg(...) 66 111 #endif 67 112 113 #if CONFIG_EXEC_DEBUG 114 #define exec_dmsg(...) printk(__VA_ARGS__) 115 #else 116 #define exec_dmsg(...) 117 #endif 118 119 #if CONFIG_FBF_DEBUG 120 #define fbf_dmsg(...) printk(__VA_ARGS__) 121 #else 122 #define fbf_dmsg(...) 123 #endif 124 68 125 #if CONFIG_FORK_DEBUG 69 #define fork_dmsg(...) printk(__VA_ _ARGS__)126 #define fork_dmsg(...) printk(__VA_ARGS__) 70 127 #else 71 128 #define fork_dmsg(...) 72 129 #endif 73 130 74 #if CONFIG_EXEC_DEBUG75 #define exec_dmsg(...) printk(__VA__ARGS__)76 #else77 #define exec_dmsg(...)78 #endif79 80 131 #if CONFIG_ICU_DEBUG 81 #define icu_dmsg(...) printk(__VA_ _ARGS__)132 #define icu_dmsg(...) printk(__VA_ARGS__) 82 133 #else 83 134 #define icu_dmsg(...) … … 85 136 86 137 #if CONFIG_IOC_DEBUG 87 #define ioc_dmsg(...) printk(__VA_ _ARGS__)138 #define ioc_dmsg(...) printk(__VA_ARGS__) 88 139 #else 89 140 #define ioc_dmsg(...) 141 #endif 142 143 #if CONFIG_KCM_DEBUG 144 #define kcm_dmsg(...) printk(__VA_ARGS__) 145 #else 146 #define kcm_dmsg(...) 147 #endif 148 149 #if CONFIG_KHM_DEBUG 150 #define khm_dmsg(...) printk(__VA_ARGS__) 151 #else 152 #define khm_dmsg(...) 90 153 #endif 91 154 … … 102 165 #endif 103 166 167 #if CONFIG_MAPPER_DEBUG 168 #define mapper_dmsg(...) printk(__VA_ARGS__) 169 #else 170 #define mapper_dmsg(...) 171 #endif 172 104 173 #if CONFIG_MMC_DEBUG 105 #define mmc_dmsg(...) printk(__VA_ _ARGS__)174 #define mmc_dmsg(...) printk(__VA_ARGS__) 106 175 #else 107 176 #define mmc_dmsg(...) … … 109 178 110 179 #if CONFIG_NIC_DEBUG 111 #define nic_dmsg(...) printk(__VA_ _ARGS__)180 #define nic_dmsg(...) printk(__VA_ARGS__) 112 181 #else 113 182 #define nic_dmsg(...) … … 115 184 116 185 #if CONFIG_PIC_DEBUG 117 #define pic_dmsg(...) printk(__VA_ _ARGS__)186 #define pic_dmsg(...) printk(__VA_ARGS__) 118 187 #else 119 188 #define pic_dmsg(...) 120 189 #endif 121 190 191 #if CONFIG_PPM_DEBUG 192 #define ppm_dmsg(...) printk(__VA_ARGS__) 193 #else 194 #define ppm_dmsg(...) 195 #endif 196 122 197 #if CONFIG_PROCESS_DEBUG 123 #define process_dmsg(...) printk(__VA_ _ARGS__)198 #define process_dmsg(...) printk(__VA_ARGS__) 124 199 #else 125 200 #define process_dmsg(...) … … 127 202 128 203 #if CONFIG_RPC_DEBUG 129 #define rpc_dmsg(...) printk(__VA_ _ARGS__)204 #define rpc_dmsg(...) printk(__VA_ARGS__) 130 205 #else 131 206 #define rpc_dmsg(...) … … 133 208 134 209 #if CONFIG_SCHED_DEBUG 135 #define sched_dmsg(...) printk(__VA_ _ARGS__)210 #define sched_dmsg(...) printk(__VA_ARGS__) 136 211 #else 137 212 #define sched_dmsg(...) … … 139 214 140 215 #if CONFIG_THREAD_DEBUG 141 #define thread_dmsg(...) printk(__VA_ _ARGS__)216 #define thread_dmsg(...) printk(__VA_ARGS__) 142 217 #else 143 218 #define thread_dmsg(...) … … 145 220 146 221 #if CONFIG_TXT_DEBUG 147 #define txt_dmsg(...) printk(__VA_ _ARGS__)222 #define txt_dmsg(...) printk(__VA_ARGS__) 148 223 #else 149 224 #define txt_dmsg(...) … … 151 226 152 227 #if CONFIG_VFS_DEBUG 153 #define vfs_dmsg(...) printk(__VA_ _ARGS__)228 #define vfs_dmsg(...) printk(__VA_ARGS__) 154 229 #else 155 230 #define vfs_dmsg(...) … … 157 232 158 233 #if CONFIG_VMM_DEBUG 159 #define vmm_dmsg(...) printk(__VA_ _ARGS__)234 #define vmm_dmsg(...) printk(__VA_ARGS__) 160 235 #else 161 236 #define vmm_dmsg(...) -
trunk/kernel/kern/process.c
r1 r5 271 271 spinlock_lock( &process->th_lock ); 272 272 273 // first loop on threads to send the THREAD_SIG_KILL signal to all p eocess threads273 // first loop on threads to send the THREAD_SIG_KILL signal to all process threads 274 274 // we use both "ltid" and "count" indexes, because it can exist "holes" in th_tbl 275 275 for( ltid = 0 , count = 0 ; -
trunk/kernel/kern/remote_sem.c
r1 r5 101 101 { 102 102 rpc_semaphore_alloc_client( ref_cxy , &sem_xp ); 103 sem_ptr = (remote_sem_t *)GET_PTR( sem_xp ); 103 104 } 104 105 -
trunk/kernel/kern/rpc.c
r1 r5 33 33 #include <core.h> 34 34 #include <mapper.h> 35 #include < device.h>35 #include <chdev.h> 36 36 #include <bits.h> 37 37 #include <thread.h> … … 55 55 &rpc_thread_user_create_server, // 4 56 56 &rpc_thread_kernel_create_server, // 5 57 &rpc_ icu_wti_alloc_server,// 658 &rpc_ device_alloc_server,// 757 &rpc_undefined, // 6 58 &rpc_undefined, // 7 59 59 &rpc_undefined, // 8 60 60 &rpc_undefined, // 9 … … 1018 1018 1019 1019 ///////////////////////////////////////////////////////////////////////////////////////// 1020 // Marshaling functions attached to RPC_ICU_WTI_ALLOC1021 /////////////////////////////////////////////////////////////////////////////////////////1022 1023 //////////////////////////////////////////////1024 void rpc_icu_wti_alloc_client( cxy_t cxy,1025 uint32_t * wti_id ) // out1026 {1027 // RPC must be remote1028 if( cxy == local_cxy )1029 {1030 printk("PANIC in %s : target is not remote\n", __FUNCTION__ );1031 hal_core_sleep();1032 }1033 1034 // initialise RPC descriptor header1035 rpc_desc_t rpc;1036 rpc.index = RPC_ICU_WTI_ALLOC;1037 rpc.response = 1;1038 1039 // register RPC request in remote RPC fifo1040 rpc_send_sync( cxy , &rpc );1041 1042 // get output argument from rpc descriptor1043 *wti_id = (uint32_t)rpc.args[0];1044 }1045 1046 //////////////////////////////////////////1047 void rpc_icu_wti_alloc_server( xptr_t xp )1048 {1049 uint32_t wti_id;1050 1051 // get client cluster identifier and pointer on RPC descriptor1052 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1053 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1054 1055 // call icu_wti_alloc() function1056 wti_id = dev_icu_wti_alloc();1057 1058 // set output argument1059 hal_remote_swd( XPTR( client_cxy , &desc->args[0] ) , (uint64_t)wti_id);1060 }1061 1062 /////////////////////////////////////////////////////////////////////////////////////////1063 // Marshaling functions attached to RPC_DEVICE_ALLOC1064 /////////////////////////////////////////////////////////////////////////////////////////1065 1066 /////////////////////////////////////////////1067 void rpc_device_alloc_client( cxy_t cxy,1068 xptr_t * dev_xp, // out1069 error_t * error ) // out1070 {1071 // RPC must be remote1072 if( cxy == local_cxy )1073 {1074 printk("PANIC in %s : target is not remote\n", __FUNCTION__ );1075 hal_core_sleep();1076 }1077 1078 // initialise RPC descriptor header1079 rpc_desc_t rpc;1080 rpc.index = RPC_DEVICE_ALLOC;1081 rpc.response = 1;1082 1083 // register RPC request in remote RPC fifo1084 rpc_send_sync( cxy , &rpc );1085 1086 // get output argument from rpc descriptor1087 *dev_xp = (xptr_t)rpc.args[0];1088 *error = (error_t)rpc.args[1];1089 }1090 1091 /////////////////////////////////////////1092 void rpc_device_alloc_server( xptr_t xp )1093 {1094 error_t error;1095 kmem_req_t req;1096 device_t * dev_ptr;1097 xptr_t dev_xp;1098 1099 // get client cluster identifier and pointer on RPC descriptor1100 cxy_t client_cxy = (cxy_t)GET_CXY( xp );1101 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );1102 1103 // allocate memory for a device descriptor1104 req.type = KMEM_DEVICE;1105 req.flags = AF_ZERO;1106 dev_ptr = (device_t *)kmem_alloc( &req );1107 1108 // set output arguments1109 error = ( dev_ptr == NULL );1110 dev_xp = XPTR( local_cxy , dev_ptr );1111 hal_remote_swd( XPTR( client_cxy , &desc->args[0] ) , (uint64_t)dev_xp );1112 hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );1113 }1114 1115 1116 /////////////////////////////////////////////////////////////////////////////////////////1117 1020 // Marshaling functions attached to RPC_FATFS_GET_CLUSTER 1118 1021 ///////////////////////////////////////////////////////////////////////////////////////// … … 1190 1093 bool_t first; 1191 1094 reg_t sr_save; 1095 1096 printk("\n@@@ coucou 0\n"); 1192 1097 1193 1098 // get client CPU and cluster coordinates … … 1220 1125 while( error ); 1221 1126 1127 printk("\n@@@ coucou 1\n"); 1128 1222 1129 rpc_dmsg("\n[INFO] %s on core %d in cluster %x sent RPC %p to cluster %x\n", 1223 1130 __FUNCTION__ , client_lid , client_cxy , rpc , server_cxy ); … … 1240 1147 } 1241 1148 1149 printk("\n@@@ coucou 2\n"); 1150 1242 1151 // activate preemption to allow incoming RPC and avoid deadlock 1243 1152 if( this->type == THREAD_RPC ) hal_enable_irq( &sr_save ); … … 1248 1157 if( rpc->response == 0 ) break; 1249 1158 } 1159 1160 printk("\n@@@ coucou 3\n"); 1250 1161 1251 1162 // restore preemption … … 1425 1336 error_t error; 1426 1337 1427 // donothing if light lock already taken or FIFO empty1338 // calling thread does nothing if light lock already taken or FIFO empty 1428 1339 if( (rpc_fifo->owner != 0) || (local_fifo_is_empty( &rpc_fifo->fifo )) ) 1429 1340 { … … 1431 1342 } 1432 1343 1433 // The calling thread tryto take the light lock,1434 // and activate an RPC thread if success1344 // calling thread tries to take the light lock, 1345 // and activates an RPC thread if success 1435 1346 if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) ) 1436 1347 { … … 1452 1363 return false; 1453 1364 } 1454 } // end __rpc_check()1365 } // end rpc_check() 1455 1366 1456 1367 -
trunk/kernel/kern/rpc.h
r1 r5 63 63 RPC_THREAD_USER_CREATE = 4, 64 64 RPC_THREAD_KERNEL_CREATE = 5, 65 RPC_ICU_WTI_ALLOC = 6,66 RPC_DEVICE_ALLOC = 7,67 65 68 66 RPC_VFS_INODE_CREATE = 10, … … 465 463 466 464 /*********************************************************************************** 467 * The RPC_ICU_WTI_ALLOC can be send by any thread running in a "client" cluster468 * to get a WTI mailbox from the ICU of a "server" cluster.469 * The WTI is allocated from the server ICU, but the WTI is not enabled,470 * and no target core is selected in remote cluster.471 * It returns wti_id == -1 if there is no free WTI in server cluster.472 ***********************************************************************************473 * @ cxy : server cluster identifier.474 * @ wti_id : [out] local pointer on WTI index in client cluster (-1 if error).475 **********************************************************************************/476 void rpc_icu_wti_alloc_client( cxy_t cxy,477 uint32_t * wti_id );478 479 void rpc_icu_wti_alloc_server( xptr_t xp );480 481 /***********************************************************************************482 * The RPC_DEVICE_ALLOC can be send by any thread running in a "client" cluster483 * to create a device descriptor in a remote "server" cluster.484 * The WTI is allocated from the server ICU, but the WTI is not enabled,485 * and no target core is selected in remote cluster.486 * It returns wti_id == -1 if there is no free WTI in server cluster.487 ***********************************************************************************488 * @ cxy : server cluster identifier.489 * @ dev_xp : [out] buffer for extended pointer on device (in client cluster).490 * @ error : [out] local pointer on buffer for error code (in client cluster).491 **********************************************************************************/492 void rpc_device_alloc_client( cxy_t cxy,493 xptr_t * dev_xp,494 error_t * error );495 496 void rpc_device_alloc_server( xptr_t xp );497 498 /***********************************************************************************499 465 * The RPC_FATFS_GET_CLUSTER can be send by any thread running in a "client" cluster 500 466 * to scan the FAT mapper, stored in a remote "server" cluster, and get the FATFS -
trunk/kernel/kern/signal.c
r1 r5 2 2 * signal.c - signal-management related operations implementation 3 3 * 4 * Author Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Mohamed Lamine Karaoui (2015) 6 * Alain Greiner (2016) 4 * Author Alain Greiner (2016,2017) 7 5 * 8 6 * Copyright (c) UPMC Sorbonne Universites … … 55 53 } 56 54 57 //////////////////////////////////////// 58 error_t signal_init( thread_t * thread ) 59 { 60 thread->info.sig_state = 0; 61 thread->info.sig_mask = CURRENT_THREAD->info.sig_mask; 62 return 0; 63 } 64 65 //////////////////////////////////////////////////// 66 static error_t signal_rise_all( process_t * process, 67 uint32_t sig ) 55 ////////////////////////////////////// 56 void signal_rise( process_t * process, 57 uint32_t sig ) 68 58 { 69 59 thread_t * thread; … … 83 73 __FUNCTION__, process->th_nr , process->pid ); 84 74 85 return 0; 86 } 87 88 //////////////////////////////////////////////////// 89 static error_t signal_rise_one( process_t * process, 90 uint32_t sig ) 91 { 92 thread_t * thread; 93 94 spinlock_lock( &process->th_lock ); 95 96 //mdify to current_thread, not the one pointed by the sig_mgr ? 97 if(process->sig_mgr.handler == NULL) 98 thread = list_first(&process->th_root, struct thread_s, rope); 99 else 100 thread = process->sig_mgr.handler; 101 102 spinlock_lock( &thread->lock ); 103 thread->info.sig_state |= (1 << sig); 104 spinlock_unlock( &thread->lock ); 105 106 spinlock_unlock( &process->th_lock ); 107 108 sig_dmsg("\n[INFO] %s : Thread %u of process %u has received signal %u. sig_state = %x\n", \ 109 __FUNCTION__, thread_current_cpu(thread)->gid, \ 110 process->pid, sig, thread->info.sig_state); 111 112 return 0; 113 } 114 75 } // end signal_rise() 76 77 /////////////////////////////////////////// 115 78 RPC_DECLARE( __signal_rise, \ 116 79 RPC_RET( RPC_RET_PTR(error_t, err)), \ … … 183 146 } 184 147 185 ////////////////////////////////// 186 error_t signal_rise( pid_t pid, 187 cxy_t location, 188 uint32_t sig) 189 { 190 error_t err; 191 192 /* Check location error */ 193 if ( location == CID_NULL ) 194 { 195 err = ESRCH; 196 printk(WARNING, "%s: there is no process with pid %u\n", \ 197 __FUNCTION__, pid); 198 return err; 199 } 200 201 err = EAGAIN; 202 RCPC( location, RPC_PRIO_SIG_RISE, __signal_rise, \ 203 RPC_RECV( RPC_RECV_OBJ(err) ), \ 204 RPC_SEND( RPC_SEND_OBJ(pid), \ 205 RPC_SEND_OBJ(sig)) \ 206 ); 207 208 return err; 148 /////////////////////////////// 149 error_t sys_kill( pid_t pid, 150 uint32_t sig) 151 { 152 cxy_t owner_cxy; // process owner cluster 153 lpid_t owner_lpid; // local process identifier 154 xptr_t root_xp; // extended pointer on root of xlist of process copies 155 xptr_t lock_xp; // extended pointer on remote_spinlock protecting this list 156 xptr_t iter_xp; // iterator for process copies list 157 xptr_t process_xp; // local pointer on process copy 158 cxy_t process_cxy; // cluster of process copy 159 process_t * process_ptr; // local pointer on process copy 160 error_t error; 161 162 // get local pointer on local cluster manager 163 cluster_t * cluster = LOCAL_CLUSTER; 164 165 // get owner process cluster and lpid 166 owner_cxy = CXY_FROM_PID( pid ); 167 owner_lpid = LPID_FROM_PID( pid ); 168 169 // get extended pointers on copies root and lock 170 root_xp = XPTR( owner_cxy , &cluster->copies_root[lpid] ); 171 lock_xp = XPTR( owner_cxy , &cluster->copies_lock[lpid] ); 172 173 // take the lock protecting the copies 174 remote_spinlock_lock( lock_xp ); 175 176 // TODO the loop below sequencialize the RPCs 177 // they could be pipelined... 178 179 // traverse the list of copies 180 XLIST_FOREACH( root_xp , iter_xp ) 181 { 182 process_xp = XLIST_ELEMENT( iter_xp , process_t , copies_list ); 183 process_cxy = GET_CXY( process_xp ); 184 process_ptr = (process_t *)GET_PTR( process_xp ); 185 186 if( process_xy == local_cxy ) // process copy is local 187 { 188 error = signal_rise( process_ptr , sig ); 189 } 190 else // process copy is remote 191 { 192 rpc_signal_rise_client( process_cxy , process_ptr , sig ); 193 } 194 } 195 196 return 0; 209 197 } 210 198 -
trunk/kernel/kern/signal.h
r1 r5 128 128 { 129 129 sa_handler_t * sigactions[SIG_NR]; 130 sterstruct thread_s * handler;130 struct thread_s * handler; 131 131 } 132 132 sig_mgr_t; … … 145 145 146 146 /******************************************************************************************* 147 * This function TODO 147 * This function register the signal <sig> in the bit_vector of all threads of a given 148 * process identified by its <pid>, in all clusters containing threads for this process. 149 * It can be executed by any thread running in any cluster, as this function uses 150 * remote access to traverse the list of process copies, and the RPC_RISE_SIGNAL 151 * to deliver the signal to all involved clusters. 152 * The list of process copies is rooted in the owner cluster. 148 153 ******************************************************************************************/ 149 154 int sys_kill( pid_t pid, … … 156 161 157 162 /******************************************************************************************* 158 * This function TODO 163 * This function register the signal <sig> in the bit-vector of all threads of a given 164 * process identified by its <pid>, in a given cluster. 165 * It must be executed by a thread running in the same cluster as the target threads 166 * (can be a local thread or a RPC thread). 159 167 ******************************************************************************************/ 160 error_t signal_init( struct thread_s * thread ); 161 162 /******************************************************************************************* 163 * This function register the signal <sig> in the bit-vector of all threads of a given 164 * process identified by its <pid>, on all clusters containing a thread . 165 * It can be executed by any thread running in any cluster. 166 ******************************************************************************************/ 167 error_t signal_rise( pid_t pid, 168 uint32_t sig ); 168 error_t signal_rise( struct process_s * process, 169 uint32_t sig ); 169 170 170 171 /******************************************************************************************* -
trunk/kernel/kern/thread.c
r1 r5 8 8 * Copyright (c) UPMC Sorbonne Universites 9 9 * 10 * This file is part of ALMOS-MKH. .10 * This file is part of ALMOS-MKH. 11 11 * 12 * ALMOS-MKH .is free software; you can redistribute it and/or modify it12 * ALMOS-MKH is free software; you can redistribute it and/or modify it 13 13 * under the terms of the GNU General Public License as published by 14 14 * the Free Software Foundation; version 2.0 of the License. 15 15 * 16 * ALMOS-MKH .is distributed in the hope that it will be useful, but16 * ALMOS-MKH is distributed in the hope that it will be useful, but 17 17 * WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 20 20 * 21 21 * You should have received a copy of the GNU General Public License 22 * along with ALMOS-MKH .; if not, write to the Free Software Foundation,22 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 23 23 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 24 */ … … 62 62 }; 63 63 64 ////////////////////////////////////////////////////////////////////////////////////// 65 // This static function returns a printable string for the thread type. 66 ////////////////////////////////////////////////////////////////////////////////////// 67 char * thread_type_str( uint32_t type ) 68 { 69 if ( type == THREAD_USER ) return "THREAD_USER"; 70 else if( type == THREAD_RPC ) return "THREAD_RPC"; 71 else if( type == THREAD_DEV ) return "THREAD_DEV"; 72 else if( type == THREAD_KERNEL ) return "THREAD_KERNEL"; 73 else if( type == THREAD_IDLE ) return "THREAD_IDLE"; 74 else return "undefined"; 75 } 76 64 77 ///////////////////////////////////////////////////////////////////////////////////// 65 78 // This static function makes the actual allocation and initialisation for a thread … … 76 89 // @ core_lid : target core local index. 77 90 ///////////////////////////////////////////////////////////////////////////////////// 78 static error_t __thread_create( thread_t ** new_thread,79 80 81 82 83 84 85 91 static error_t thread_create( thread_t ** new_thread, 92 process_t * process, 93 thread_type_t type, 94 void * func, 95 void * args, 96 lid_t core_lid, 97 intptr_t u_stack_base, 98 uint32_t u_stack_size ) 86 99 { 87 100 error_t error; … … 171 184 *new_thread = thread; 172 185 return 0; 173 } // end __thread_create()186 } // end thread_create() 174 187 175 188 … … 185 198 lid_t core_lid; // selected core local index 186 199 200 thread_dmsg("\n[INFO] %s : enters\n", 201 __FUNCTION__ ); 202 187 203 cluster_t * local_cluster = LOCAL_CLUSTER; 188 204 … … 199 215 200 216 // make allocation / initialisation 201 error = __thread_create( &thread,202 203 204 205 206 207 208 217 error = thread_create( &thread, 218 process, 219 THREAD_USER, 220 attr->entry_func, 221 attr->entry_args, 222 core_lid, 223 u_stack_base, 224 u_stack_size ); 209 225 if( error ) return ENOMEM; 210 226 … … 220 236 error = hal_fpu_context_create( thread ); 221 237 if( error ) return ENOMEM; 222 223 thread_dmsg(" INFO : %s thread %x for process %x on core %d in cluster %x\n",224 __FUNCTION__, thread->trdid, process->pid, core_lid, local_cluster->cxy);238 239 thread_dmsg("\n[INFO] %s : exit / trdid = %x / process %x / core = %d\n", 240 __FUNCTION__ , thread->trdid , process->pid , core_lid ); 225 241 226 242 *new_thread = thread; … … 239 255 lid_t core_lid; // selected core local index 240 256 257 thread_dmsg("\n[INFO] %s : enters\n", 258 __FUNCTION__ ); 259 241 260 // select a target core in local cluster 242 261 core_lid = cluster_select_local_core(); … … 246 265 247 266 // make allocation / initialisation 248 error = __thread_create( &new,249 250 251 252 253 254 255 267 error = thread_create( &new, 268 process, 269 THREAD_USER, 270 this->entry_func, 271 this->entry_args, 272 core_lid, 273 u_stack_base, 274 u_stack_size ); 256 275 if( error ) return ENOMEM; 257 276 … … 268 287 269 288 thread_dmsg("INFO : %s thread %x for process %x on core %d in cluster %x\n", 270 __FUNCTION__, new->trdid, process->pid, core_lid, local_c luster->cxy );289 __FUNCTION__, new->trdid, process->pid, core_lid, local_cxy ); 271 290 272 291 *new_thread = new; 273 292 return 0; 293 274 294 } // end thread_user_fork() 275 295 … … 286 306 thread_t * new; // pointer on new thread descriptor 287 307 288 cluster_t * local_cluster = LOCAL_CLUSTER; 289 290 // check type argument 291 if( (type != THREAD_KERNEL) && (type != THREAD_RPC) && 292 (type != THREAD_IDLE) && (type != THREAD_DEV) ) 293 { 294 printk("ERROR : %s received an illegal thread type\n", __FUNCTION__ ); 295 hal_core_sleep(); 296 } 297 298 // check core local index 299 if( core_lid >= local_cluster->cores_nr ) 300 { 301 printk("ERROR : %s received an illegal core_lid\n", __FUNCTION__ ); 302 hal_core_sleep(); 303 } 308 thread_dmsg("\n[INFO] %s : enters for %s in cluster %x\n", 309 __FUNCTION__ , thread_type_str( type ) , local_cxy ); 310 311 assert( ( (type == THREAD_KERNEL) || (type == THREAD_RPC) || 312 (type == THREAD_IDLE) || (type == THREAD_DEV) ) , 313 __FUNCTION__ , "illegal thread type" ); 314 315 assert( (core_lid < LOCAL_CLUSTER->cores_nr) , 316 __FUNCTION__ , "illegal core_lid" ); 304 317 305 318 // make allocation / initialisation 306 error = __thread_create( &new,307 308 309 310 311 312 319 error = thread_create( &new, 320 &process_zero, 321 type, 322 func, 323 args, 324 core_lid, 325 0 , 0 ); // no user stack for a kernel thread 313 326 if( error ) 314 327 { 315 printk(" ERROR : %scannot create thread\n", __FUNCTION__ );316 hal_core_sleep();328 printk("\n[ERROR] in %s : cannot create thread\n", __FUNCTION__ ); 329 return ENOMEM; 317 330 } 318 331 … … 320 333 hal_cpu_context_create( new ); 321 334 322 thread_dmsg(" INFO : %s thread %x in cluster %x on core%d\n",323 __FUNCTION__ , new->trdid , local_cluster->cxy ,core_lid );335 thread_dmsg("\n[INFO] %s : sucessfully exit / trdid = %x / core = %d\n", 336 __FUNCTION__ , new->trdid , core_lid ); 324 337 325 338 *new_thread = new; 326 339 return 0; 340 327 341 } // end thread_kernel_create() 328 342 … … 341 355 core_t * core = thread->core; 342 356 343 if( thread->children_nr ) 344 { 345 printk("\n[PANIC] in %s : thread %x for process %x on core %d in cluster %x" 346 " has still attached children\n", 347 __FUNCTION__, thread->trdid, process->pid, core->lid, local_cxy ); 348 hal_core_sleep(); 349 } 350 351 if( (thread->local_locks != 0) || (thread->remote_locks != 0) ) 352 { 353 printk("\n[PANIC] in %s : thread %x for process %x on core %d in cluster %x" 354 " did not released all locks\n", 355 __FUNCTION__, thread->trdid, process->pid, core->lid, local_cxy ); 356 hal_core_sleep(); 357 } 357 thread_dmsg("\n[INFO] %s : enters for thread %x in process %x / type = %s\n", 358 __FUNCTION__ , thread->trdid , process->pid , thread_type_str( thread->type ) ); 359 360 assert( (thread->children_nr == 0) , __FUNCTION__ , "still attached children" ); 361 362 assert( (thread->local_locks == 0) , __FUNCTION__ , "all local locks not released" ); 358 363 364 assert( (thread->remote_locks == 0) , __FUNCTION__ , "all remote locks not released" ); 365 359 366 tm_start = hal_time_stamp(); 360 367 … … 402 409 tm_end = hal_time_stamp(); 403 410 404 thread_dmsg("INFO : %s destroy thread %x for process %x on core %d in cluster %x\n" 405 " / duration = %d / page_faults = %d / ticks = %d\n", 406 __FUNCTION__, trdid , pid , core_lid , local_cxy , 407 tm_end - tm_start , pgfaults , ticks ); 411 thread_dmsg("\n[INFO] %s : exit for thread %x in process %x / duration = %d\n", 412 __FUNCTION__, thread->trdid , process->pid , tm_end - tm_start ); 408 413 409 414 } // end thread_destroy() … … 592 597 while( 1 ) 593 598 { 594 thread_dmsg(" INFO: core %d in cluster %x goes to sleeping state at cycle\n",595 core->lid , cluster->cxy, hal_time_stamp() );599 thread_dmsg("\n[INFO] %s : core %d in cluster %x goes to sleeping state at cycle\n", 600 __FUNCTION__ , core->lid , local_cxy , hal_time_stamp() ); 596 601 597 602 // force core to sleeping state 598 603 hal_core_sleep(); 599 604 600 thread_dmsg(" INFO: core %d in cluster %x wake up at cycle %d\n",601 core->lid , cluster->cxy, hal_time_stamp() );605 thread_dmsg("\n[INFO] %s : core %d in cluster %x wake up at cycle %d\n", 606 __FUNCTION__ , core->lid , local_cxy , hal_time_stamp() ); 602 607 603 608 // force scheduling at wake-up -
trunk/kernel/kern/thread.h
r1 r5 40 40 #include <dev_txt.h> 41 41 #include <dev_mmc.h> 42 #include <dev_dma.h> 42 43 43 44 /*************************************************************************************** … … 196 197 txt_command_t txt; /*! TXT device generic command */ 197 198 nic_command_t nic; /*! NIC device generic command */ 198 mmc_command_t mmc; /*! NIC device generic command */ 199 mmc_command_t mmc; /*! MMC device generic command */ 200 dma_command_t dma; /*! DMA device generic command */ 199 201 } 200 dev;202 command; 201 203 202 204 cxy_t rpc_client_cxy; /*! client cluster index (for a RPC thread) */
Note: See TracChangeset
for help on using the changeset viewer.