Changeset 5 for trunk/kernel/kern/kernel_init.c
- Timestamp:
- Apr 26, 2017, 2:11:56 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note: See TracChangeset
for help on using the changeset viewer.