Changeset 188 for trunk/kernel/kern/kernel_init.c
- Timestamp:
- Jul 12, 2017, 8:12:41 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/kernel_init.c
r127 r188 85 85 cluster_t cluster_manager CONFIG_CACHE_LINE_ALIGNED; 86 86 87 // This variable defines the TXT0 kernel terminal 88 __attribute__((section(".kdata"))) 89 chdev_t txt0_chdev CONFIG_CACHE_LINE_ALIGNED; 90 87 91 // This variables define the kernel process0 descriptor 88 92 __attribute__((section(".kdata"))) … … 93 97 chdev_directory_t chdev_dir CONFIG_CACHE_LINE_ALIGNED; 94 98 95 // This variable contains the input IRQ indexes for the PIC device99 // This variable contains the input IRQ indexes for the IOPIC controller 96 100 __attribute__((section(".kdata"))) 97 chdev_pic_input_t chdev_pic_inputCONFIG_CACHE_LINE_ALIGNED;98 99 // This variable contains the input IRQ indexes for the ICU device101 iopic_input_t iopic_input CONFIG_CACHE_LINE_ALIGNED; 102 103 // This variable contains the input IRQ indexes for the LAPIC controller 100 104 __attribute__((section(".kdata"))) 101 chdev_icu_input_t chdev_icu_inputCONFIG_CACHE_LINE_ALIGNED;105 lapic_input_t lapic_input CONFIG_CACHE_LINE_ALIGNED; 102 106 103 107 // This variable defines the local cluster identifier 104 108 __attribute__((section(".kdata"))) 105 109 cxy_t local_cxy CONFIG_CACHE_LINE_ALIGNED; 106 107 // This variable defines the TXT0 chdev descriptor108 __attribute__((section(".kdata")))109 chdev_t txt0_chdev CONFIG_CACHE_LINE_ALIGNED;110 110 111 111 // This variable is used for CP0 cores synchronisation in kernel_init() … … 142 142 143 143 /////////////////////////////////////////////////////////////////////////////////////////// 144 // This static function initializes the TXT0 chdev descriptor, associated to the "kernel 145 // terminal", and shared by all kernel instances for debug messages. It also registers it 146 // in the chdev directory, containing extended pointers on all chdevs. 147 // The global variable txt0_chdev is replicated in all clusters, but only the chdev 148 // allocated in I/O cluster is used by ALMOS-MKH. 149 // Therefore, this function must be called by a thread running in the I/O cluster. 144 // This function initializes the TXT0 chdev descriptor, that is the "kernel terminal", 145 // shared by all kernel instances for debug messages. 146 // It is a global variable (replicated in all clusters), because this terminal is used 147 // before the kmem allocator initialisation, but only the instance in cluster containing 148 // the calling core is registered in the "chdev_dir" directory. 150 149 // As this TXT0 chdev supports only the TXT_SYNC_WRITE command, we don't create 151 150 // a server thread, we don't allocate a WTI, and we don't initialize the waiting queue. … … 158 157 uint32_t dev_nr; // actual number of devices in this cluster 159 158 xptr_t base; // remote pointer on segment base 160 uint32_t type; // peripheral type161 159 uint32_t func; // device functional index 162 160 uint32_t impl; // device implementation index … … 164 162 uint32_t x; // X cluster coordinate 165 163 uint32_t y; // Y cluster coordinate 164 uint32_t channels; // number of channels 166 165 167 166 // get number of peripherals and base of devices array from boot_info … … 173 172 { 174 173 base = dev_tbl[i].base; 175 type = dev_tbl[i].type;176 func = FUNC_FROM_TYPE(type );177 impl = IMPL_FROM_TYPE( type );174 func = FUNC_FROM_TYPE( dev_tbl[i].type ); 175 impl = IMPL_FROM_TYPE( dev_tbl[i].type ); 176 channels = dev_tbl[i].channels; 178 177 179 178 if (func == DEV_FUNC_TXT ) 180 179 { 181 // initialize basic fields 182 txt0_chdev.func = func; 183 txt0_chdev.impl = impl; 184 txt0_chdev.channel = 0; 185 txt0_chdev.is_rx = 0; 186 txt0_chdev.base = base; 187 188 // initialize lock 180 assert( (channels > 0) , __FUNCTION__ , 181 "numner of TXT channels cannot be 0\n"); 182 183 // initializes TXT0 basic fields 184 txt0_chdev.func = func; 185 txt0_chdev.impl = impl; 186 txt0_chdev.channel = 0; 187 txt0_chdev.base = base; 188 txt0_chdev.is_rx = false; 189 190 // initializes lock 189 191 remote_spinlock_init( XPTR( local_cxy , &txt0_chdev.wait_lock ) ); 190 191 // TODO use generic device initialisation 192 // hal_drivers_txt_init( &txt0_chdev ); 193 194 if( impl == IMPL_TXT_TTY ) 195 { 196 txt0_chdev.cmd = &soclib_tty_cmd; 197 txt0_chdev.isr = &soclib_tty_isr; 198 soclib_tty_init( &txt0_chdev ); 199 } 200 201 // initialize the replicated chdev_dir[x][y] structures 192 193 // TXT specific initialisation: 194 // no server thread & no IRQ routing for channel 0 195 dev_txt_init( &txt0_chdev ); 196 197 // register the TXT0 in all chdev_dir[x][y] structures 202 198 for( x = 0 ; x < info->x_size ; x++ ) 203 199 { … … 210 206 } 211 207 212 kinit_dmsg("\n[INFO] %s : core[%x][0] created TXT0 chdev" 213 " / paddr = %l at cycle %d\n", 214 __FUNCTION__ , local_cxy , chdev_func_str( func ), 215 XPTR(local_cxy , &txt0_chdev) , hal_get_cycles() ); 216 } 217 } 218 } 219 220 /////////////////////////////////////////////////////////////////////////////////////////// 221 // This static function allocates memory for the chdev (channel_device) descriptors 222 // associated to the internal peripherals contained in the local cluster. These internal 223 // devices (ICU, MMC, DMA) chdev descriptors are placed in the local cluster. 224 // It initialises these device descriptors as specified by the boot_info_t structure, 225 // including the dynamic linking with the driver for the specified implementation. 226 // Finally, all copies of the devices directory are initialised. 208 kinit_dmsg("\n[INFO] %s created TXT0 chdev in cluster %x at cycle %d\n", 209 __FUNCTION__ , local_cxy , (uint32_t)hal_time_stamp() ); 210 } 211 } // end loop on devices 212 } // end txt0_device_init() 213 214 /////////////////////////////////////////////////////////////////////////////////////////// 215 // This function allocates memory and initializes the chdev descriptors for the internal 216 // peripherals contained in the local cluster, other than the LAPIC, as specified by 217 // the boot_info, including the linking with the driver for the specified implementation. 218 // The relevant entries in all copies of the devices directory are initialised. 227 219 /////////////////////////////////////////////////////////////////////////////////////////// 228 220 // @ info : pointer on the local boot-info structure. … … 230 222 static void internal_devices_init( boot_info_t * info ) 231 223 { 232 boot_device_t * dev; // pointer on boot_info device (ICU/MMC/DMA) 233 uint32_t x; // X cluster coordinate 234 uint32_t y; // Y cluster coordinate 235 chdev_t * chdev_ptr; // local pointer on chdev descriptor 236 xptr_t chdev_xp; // extended pointer on chdev descriptor 237 238 /////////// ICU ////////// 239 240 dev = &info->dev_icu; 241 242 assert( ((info->cores_nr == 0) || (dev->channels != 0)) , __FUNCTION__ , 243 "ICU device must exist in cluster containing cores" ); 244 245 assert( (dev->channels == 1) , __FUNCTION__ , 246 "channels number must be 1 for ICU device" ); 247 248 assert( (FUNC_FROM_TYPE( dev->type ) == DEV_FUNC_ICU ) , __FUNCTION__ , 249 " inconsistent ICU device type"); 250 251 // create one chdev in local cluster 252 chdev_ptr = chdev_create( FUNC_FROM_TYPE( dev->type ), 253 IMPL_FROM_TYPE( dev->type ), 254 0, // channel 255 false, // TX 256 dev->base ); 257 258 assert( (chdev_ptr != NULL) , __FUNCTION__ , "cannot allocate ICU chdev" ); 259 260 // get extended pointer on chdev descriptor 261 chdev_xp = XPTR( local_cxy , chdev_ptr ); 262 263 // make ICU specific initialisation 264 // TODO remove these three parameters 265 dev_icu_init( chdev_ptr , dev->param0 , dev->param1 , dev->param2 ); 266 267 // initialize the ICU field in the chdev_dir[x][y] structures 268 // replicated in all clusters, and containing extended pointers 269 // on all remotely accessible devices 270 for( x = 0 ; x < info->x_size ; x++ ) 271 { 272 for( y = 0 ; y < info->y_size ; y++ ) 273 { 274 cxy_t cxy = (x<<info->y_width) + y; 275 hal_remote_swd( XPTR( cxy , &chdev_dir.icu[local_cxy] ) , chdev_xp ); 276 } 277 } 278 279 // initialize the entries of the local chdev_icu_input structure 280 // defining how internal peripherals are connected to ICU 281 uint32_t id; 282 uint8_t valid; 283 uint32_t src_type; 284 uint8_t src_ch; 285 uint32_t src_func; 286 for( id = 0 ; id < CONFIG_MAX_HWIS_PER_ICU ; id++ ) 287 { 288 valid = dev->irq[id].valid; 289 src_type = dev->irq[id].dev_type; 290 src_ch = dev->irq[id].channel; 291 src_func = FUNC_FROM_TYPE( src_type ); 292 293 if( valid ) // only valid local IRQs are registered 294 { 295 if ( src_func == DEV_FUNC_MMC ) chdev_icu_input.mmc = id; 296 else if( src_func == DEV_FUNC_DMA ) chdev_icu_input.dma[src_ch] = id; 297 else assert( false , __FUNCTION__ , "illegal source device for ICU input" ); 298 } 299 } 300 301 kinit_dmsg("\n[INFO] %s : core[%x][0] created ICU chdev at cycle %d\n", 302 __FUNCTION__ , local_cxy , hal_get_cycles() ); 303 304 /////////// MMC internal chdev /////////// 305 306 dev = &info->dev_mmc; 307 308 if( dev->channels != 0 ) // MMC device is defined 309 { 310 assert( (dev->channels == 1) , __FUNCTION__ , 311 "channels number must be 1 for MMC device" ); 312 313 assert( (FUNC_FROM_TYPE( dev->type ) == DEV_FUNC_MMC ) , __FUNCTION__ , 314 " inconsistent MMC device type"); 315 316 // create one chdev in local cluster 317 chdev_ptr = chdev_create( FUNC_FROM_TYPE( dev->type ), 318 IMPL_FROM_TYPE( dev->type ), 319 0, // channel 320 false, // TX 321 dev->base ); 322 323 assert( (chdev_ptr != NULL) , __FUNCTION__ , "cannot allocate MMC chdev" ); 324 325 // get extended pointer on chdev descriptor 326 chdev_xp = XPTR( local_cxy , chdev_ptr ); 327 328 // make MMC specific initialisation 329 dev_mmc_init( chdev_ptr ); 330 331 // initialize the MMC field in the chdev_dir[x][y] structures 332 // replicated in all clusters, and containing extended pointers 333 // on all remotely accessible devices 334 for( x = 0 ; x < info->x_size ; x++ ) 335 { 336 for( y = 0 ; y < info->y_size ; y++ ) 224 boot_device_t * dev_tbl; // pointer on array of internaldevices in boot_info 225 uint32_t dev_nr; // actual number of devices in this cluster 226 xptr_t base; // remote pointer on segment base 227 uint32_t func; // device functionnal index 228 uint32_t impl; // device implementation index 229 uint32_t i; // device index in dev_tbl 230 uint32_t x; // X cluster coordinate 231 uint32_t y; // Y cluster coordinate 232 uint32_t channels; // number of channels 233 uint32_t channel; // channel index 234 chdev_t * chdev_ptr; // local pointer on created chdev 235 236 // get number of internal peripherals and base from boot_info 237 dev_nr = info->int_dev_nr; 238 dev_tbl = info->int_dev; 239 240 // loop on internal peripherals 241 for( i = 0 ; i < dev_nr ; i++ ) 242 { 243 base = dev_tbl[i].base; 244 channels = dev_tbl[i].channels; 245 func = FUNC_FROM_TYPE( dev_tbl[i].type ); 246 impl = IMPL_FROM_TYPE( dev_tbl[i].type ); 247 248 ////////////////////////// 249 if( func == DEV_FUNC_MMC ) 250 { 251 assert( (channels == 1) , __FUNCTION__ , 252 "MMC device must be single channel\n" ); 253 254 // create chdev in local cluster 255 chdev_ptr = chdev_create( func, 256 impl, 257 0, // channel 258 false, // direction 259 base ); 260 261 assert( (chdev_ptr != NULL) , __FUNCTION__ , 262 "cannot allocate memory for MMC chdev\n" ); 263 264 // make MMC specific initialisation 265 dev_mmc_init( chdev_ptr ); 266 267 // set the MMC field in all chdev_dir[x][y] structures 268 for( x = 0 ; x < info->x_size ; x++ ) 337 269 { 338 cxy_t cxy = (x<<info->y_width) + y; 339 hal_remote_swd( XPTR( cxy , &chdev_dir.mmc[local_cxy] ) , chdev_xp ); 270 for( y = 0 ; y < info->y_size ; y++ ) 271 { 272 cxy_t cxy = (x<<info->y_width) + y; 273 hal_remote_swd( XPTR( cxy , &chdev_dir.mmc[local_cxy] ), 274 XPTR( local_cxy , chdev_ptr ) ); 275 } 340 276 } 341 } 342 343 kinit_dmsg("\n[INFO] %s : core[%x][0] created MMC chdev at cycle %d\n", 344 __FUNCTION__ , local_cxy , hal_get_cycles() ); 345 } 346 347 /////////// DMA internal chdevs ////////// 348 349 dev = &info->dev_dma; 350 351 if( dev->channels != 0 ) // DMA device is defined 352 { 353 assert( (FUNC_FROM_TYPE( dev->type ) == DEV_FUNC_DMA ) , __FUNCTION__ , 354 " inconsistent DMA device type"); 355 356 // create one chdev per channel in local cluster 357 uint32_t channel; 358 for( channel = 0 ; channel < dev->channels ; channel++ ) 359 { 360 chdev_ptr = chdev_create( FUNC_FROM_TYPE( dev->type ), 361 IMPL_FROM_TYPE( dev->type ), 362 channel, // channel 363 false, // TX 364 dev->base ); 365 366 assert( (chdev_ptr != NULL) , __FUNCTION__ , "cannot allocate DMA chdev" ); 367 368 // get extended pointer on channel descriptor 369 chdev_xp = XPTR( local_cxy , chdev_ptr ); 370 371 // make DMA specific initialisation 372 dev_dma_init( chdev_ptr ); 373 374 // initialize only the DMA[channel] field in the local chdev_dir[x][y] 375 // structure because the DMA device is not remotely accessible. 376 chdev_dir.dma[channel] = chdev_xp; 377 378 kinit_dmsg("\n[INFO] %s : core[%x][0] created DMA[%d] chdev at cycle %d\n", 379 __FUNCTION__ , local_cxy , channel , hal_get_cycles() ); 277 278 if( local_cxy == 0 ) 279 kinit_dmsg("\n[INFO] %s created MMC chdev in cluster 0 at cycle %d\n", 280 __FUNCTION__ , local_cxy , (uint32_t)hal_time_stamp() ); 281 } 282 /////////////////////////////// 283 else if( func == DEV_FUNC_DMA ) 284 { 285 // create one chdev per channel in local cluster 286 for( channel = 0 ; channel < channels ; channel++ ) 287 { 288 // create chdev[channel] in local cluster 289 chdev_ptr = chdev_create( func, 290 impl, 291 channel, 292 false, // direction 293 base ); 294 295 assert( (chdev_ptr != NULL) , __FUNCTION__ , 296 "cannot allocate memory for DMA chdev" ); 297 298 // make DMA specific initialisation 299 dev_dma_init( chdev_ptr ); 300 301 // initialize only the DMA[channel] field in the local chdev_dir[x][y] 302 // structure because the DMA device is not remotely accessible. 303 chdev_dir.dma[channel] = XPTR( local_cxy , chdev_ptr ); 304 305 kinit_dmsg("\n[INFO] %s created DMA[%d] chdev in cluster 0 at cycle %d\n", 306 __FUNCTION__ , channel , (uint32_t)hal_time_stamp() ); 307 } 380 308 } 381 309 } … … 383 311 384 312 /////////////////////////////////////////////////////////////////////////////////////////// 385 // This static function allocates memory for the chdev descriptors associated 386 // to the external (shared) peripherals contained in the local cluster. These external 387 // devices (IOB, IOC, TXT, NIC, etc ) are distributed on all clusters. 388 // It initialises these device descriptors as specified by the boot_info_t structure, 313 // This function allocates memory and initializes the chdev descriptors for the 314 // external (shared) peripherals other than the IOPIC, as specified by the boot_info, 389 315 // including the dynamic linking with the driver for the specified implementation. 390 // Finally, all copies of the devices directory are initialised. 391 // 392 // The number of channel_devices depends on the device functional type. 393 // There are three nested loops to build the full set of external channel_devices: 394 // - loop on external devices. 395 // - loop on channels for multi-channels devices. 396 // - loop on directions (RX/TX) for NIC device. 397 // The set of channel_devices is indexed by the chdev_gid global index, that is used 398 // to select the cluster containing a given chdev[func,channel,direction]. 399 // All clusters scan the full set of chdevs, but only the cluster matching 400 // (chdev_gid % (x_size*y_size)) create the corresponding chdev. 401 // 402 // TODO check that cluster IO contains a PIC [AG] 403 // TODO make a default initialisation for the chdev_dir structure (XPTR_NULL ) [AG] 316 // These chdev descriptors are distributed on all clusters, using a modulo on a global 317 // index, identically computed in all clusters: In each cluster, the local CP0 core 318 // computes the global index for all external chdevs, and creates only the chdevs that 319 // must be placed in the local cluster. 320 // The relevant entries in all copies of the devices directory are initialised. 404 321 /////////////////////////////////////////////////////////////////////////////////////////// 405 322 // @ info : pointer on the local boot-info structure. … … 407 324 static void external_devices_init( boot_info_t * info ) 408 325 { 409 boot_device_t * dev_tbl; // pointer on array of devices in boot_info 410 uint32_t dev_nr; // actual number of devices in this cluster 411 xptr_t base; // remote pointer on segment base 412 uint32_t type; // peripheral type 326 boot_device_t * dev_tbl; // pointer on array of external devices in boot_info 327 uint32_t dev_nr; // actual number of external devices 328 xptr_t base; // remote pointer on segment base 413 329 uint32_t func; // device functionnal index 414 330 uint32_t impl; // device implementation index 415 uint32_t i; // device index in dev_tbl 416 uint32_t x; // X cluster coordinate 417 uint32_t y; // Y cluster coordinate 418 uint32_t channels_nr; // number of channels 419 uint32_t channel; // channel index 420 uint32_t directions_nr; // number of directions 421 uint32_t direction; // direction index 422 uint32_t p0; // device parameter 0 423 uint32_t p1; // device parameter 1 424 uint32_t p2; // device parameter 2 425 uint32_t p3; // device parameter 3 426 uint32_t first_channel; // used in loop on channels 427 331 uint32_t i; // device index in dev_tbl 332 uint32_t x; // X cluster coordinate 333 uint32_t y; // Y cluster coordinate 334 uint32_t channels; // number of channels 335 uint32_t channel; // channel index 336 uint32_t directions; // number of directions (1 or 2) 337 uint32_t rx; // direction index (0 or 1) 338 uint32_t first_channel; // used in loop on channels for TXT 428 339 chdev_t * chdev; // local pointer on one channel_device descriptor 429 xptr_t chdev_xp; // extended pointer on channel_device descriptor 430 uint32_t chdev_gid = 0; // global index of channel_device descriptor 340 uint32_t ext_chdev_gid; // global index of external chdev 431 341 432 342 // get number of peripherals and base of devices array from boot_info … … 434 344 dev_tbl = info->ext_dev; 435 345 346 // initializes global index (PIC is already placed in cluster 0 347 ext_chdev_gid = 1; 348 436 349 // loop on external peripherals 437 350 for( i = 0 ; i < dev_nr ; i++ ) 438 351 { 439 base = dev_tbl[i].base; 440 type = dev_tbl[i].type; 441 channels_nr = dev_tbl[i].channels; 442 p0 = dev_tbl[i].param0; 443 p1 = dev_tbl[i].param1; 444 p2 = dev_tbl[i].param2; 445 p3 = dev_tbl[i].param3; 446 447 func = FUNC_FROM_TYPE( type ); 448 impl = IMPL_FROM_TYPE( type ); 352 base = dev_tbl[i].base; 353 channels = dev_tbl[i].channels; 354 func = FUNC_FROM_TYPE( dev_tbl[i].type ); 355 impl = IMPL_FROM_TYPE( dev_tbl[i].type ); 449 356 450 357 // There is one chdev per direction for NIC 451 if (func == DEV_FUNC_NIC) directions _nr= 2;452 else directions _nr= 1;358 if (func == DEV_FUNC_NIC) directions = 2; 359 else directions = 1; 453 360 454 361 // The TXT0 chdev has already been created … … 456 363 else first_channel = 0; 457 364 458 // do nothing for RO M, that does not require a device descriptor.365 // do nothing for RO, that does not require a device descriptor. 459 366 if( func == DEV_FUNC_ROM ) continue; 460 367 461 // check external device functional type 462 if( (func != DEV_FUNC_IOB) && 463 (func != DEV_FUNC_PIC) && 464 (func != DEV_FUNC_IOC) && 465 (func != DEV_FUNC_TXT) && 466 (func != DEV_FUNC_NIC) && 467 (func != DEV_FUNC_FBF) ) 468 { 469 assert( false , __FUNCTION__ , "undefined external peripheral type" ); 470 } 368 // do nothing for PIC, that is already initialized 369 if( func == DEV_FUNC_PIC ) continue; 370 371 // check PIC device initialized 372 assert( (chdev_dir.pic != XPTR_NULL ) , __FUNCTION__ , 373 "PIC device must be initialized before other devices\n" ); 374 375 // check external device functionnal type 376 assert( ( (func == DEV_FUNC_IOB) || 377 (func == DEV_FUNC_IOC) || 378 (func == DEV_FUNC_TXT) || 379 (func == DEV_FUNC_NIC) || 380 (func == DEV_FUNC_FBF) ) , __FUNCTION__ , 381 "undefined external peripheral type\n" ); 471 382 472 383 // loops on channels 473 for( channel = first_channel ; channel < channels _nr; channel++ )384 for( channel = first_channel ; channel < channels ; channel++ ) 474 385 { 475 386 // loop on directions 476 for( direction = 0 ; direction < directions_nr ; direction++ )387 for( rx = 0 ; rx < directions ; rx++ ) 477 388 { 478 // gettarget cluster for chdev[func,channel,direction]479 uint32_t offset = chdev_gid % ( info->x_size * info->y_size );389 // compute target cluster for chdev[func,channel,direction] 390 uint32_t offset = ext_chdev_gid % ( info->x_size * info->y_size ); 480 391 uint32_t cx = offset / info->y_size; 481 392 uint32_t cy = offset % info->y_size; … … 489 400 impl, 490 401 channel, 491 direction,402 rx, // direction 492 403 base ); 493 404 … … 495 406 "cannot allocate external device" ); 496 407 497 // get extended pointer on chdev498 chdev_xp = XPTR( local_cxy , chdev );499 500 408 // make device type specific initialisation 501 // the number of parameters depends on the device type502 // TODO : remove the parameters that must be provided by the drivers503 409 if ( func == DEV_FUNC_IOB ) dev_iob_init( chdev ); 504 410 else if( func == DEV_FUNC_IOC ) dev_ioc_init( chdev ); 505 411 else if( func == DEV_FUNC_TXT ) dev_txt_init( chdev ); 506 412 else if( func == DEV_FUNC_NIC ) dev_nic_init( chdev ); 507 else if( func == DEV_FUNC_PIC ) dev_pic_init( chdev , p0 ); 508 else if( func == DEV_FUNC_FBF ) dev_fbf_init( chdev , p0 , p1 ); 509 else 510 { 511 assert( false , __FUNCTION__ , "undefined device type" ); 512 } 413 else if( func == DEV_FUNC_FBF ) dev_fbf_init( chdev ); 513 414 514 415 // all external (shared) devices are remotely accessible … … 517 418 xptr_t * entry; 518 419 519 if( func == DEV_FUNC_IOB) entry = &chdev_dir.iob;520 if( func == DEV_FUNC_PIC ) entry = &chdev_dir.pic;521 if( func == DEV_FUNC_TXT) entry = &chdev_dir.txt[channel];522 if( func == DEV_FUNC_IOC ) entry = &chdev_dir.ioc[channel];523 if( func == DEV_FUNC_FBF ) entry = &chdev_dir.fbf[channel];524 if( func == DEV_FUNC_NIC ) entry = &chdev_dir.nic_tx[channel];420 if(func==DEV_FUNC_IOB ) entry = &chdev_dir.iob; 421 if(func==DEV_FUNC_IOC ) entry = &chdev_dir.ioc[channel]; 422 if(func==DEV_FUNC_TXT ) entry = &chdev_dir.txt[channel]; 423 if(func==DEV_FUNC_FBF ) entry = &chdev_dir.fbf[channel]; 424 if((func==DEV_FUNC_NIC) && (rx==0)) entry = &chdev_dir.nic_tx[channel]; 425 if((func==DEV_FUNC_NIC) && (rx==1)) entry = &chdev_dir.nic_rx[channel]; 525 426 526 427 for( x = 0 ; x < info->x_size ; x++ ) … … 529 430 { 530 431 cxy_t cxy = (x<<info->y_width) + y; 531 hal_remote_swd( XPTR( cxy , entry ) , chdev_xp ); 432 hal_remote_swd( XPTR( cxy , entry ), 433 XPTR( local_cxy , chdev ) ); 532 434 } 533 435 } 534 436 535 kinit_dmsg("\n[INFO] %s : core[%x][0] create chdev %s[%d]at cycle %d\n",536 __FUNCTION__ , local_cxy , chdev_func_str( func ),537 channel , hal_get_cycles() );437 kinit_dmsg("\n[INFO] %s create chdev %s[%d] in cluster %x at cycle %d\n", 438 __FUNCTION__ , chdev_func_str( func ), channel, 439 local_cxy , (uint32_t)hal_time_stamp() ); 538 440 539 441 } // end if match 540 442 541 443 // increment chdev global index (matching or not) 542 chdev_gid++;444 ext_chdev_gid++; 543 445 544 446 } // end loop on directions 545 546 447 } // end loop on channels 547 548 // initialize the entries of the local chdev_pic_input structure 549 // defining how external peripherals are connected to PIC 448 } // end loop on devices 449 } // end external_devices_init() 450 451 /////////////////////////////////////////////////////////////////////////////////////////// 452 // This function is called by CP0 in cluster 0 to allocate memory and initialize the PIC 453 // device, namely the informations attached to the external IOPIC controller. 454 // This initialisation must be done before other devices initialisation because the IRQ 455 // routing infrastructure is required for internal and external devices initialisation. 456 /////////////////////////////////////////////////////////////////////////////////////////// 457 // @ info : pointer on the local boot-info structure. 458 /////////////////////////////////////////////////////////////////////////////////////////// 459 static void iopic_init( boot_info_t * info ) 460 { 461 boot_device_t * dev_tbl; // pointer on boot_info external devices array 462 uint32_t dev_nr; // actual number of external devices 463 xptr_t base; // remote pointer on segment base 464 uint32_t func; // device functionnal index 465 uint32_t impl; // device implementation index 466 uint32_t i; // device index in dev_tbl 467 uint32_t x; // cluster X coordinate 468 uint32_t y; // cluster Y coordinate 469 bool_t found; // IOPIC found 470 chdev_t * chdev; // pointer on PIC chdev descriptor 471 472 // get number of external peripherals and base of array from boot_info 473 dev_nr = info->ext_dev_nr; 474 dev_tbl = info->ext_dev; 475 476 // loop on external peripherals to get the IOPIC 477 for( i = 0 , found = false ; i < dev_nr ; i++ ) 478 { 479 func = FUNC_FROM_TYPE( dev_tbl[i].type ); 480 550 481 if( func == DEV_FUNC_PIC ) 551 482 { 552 uint32_t id; 553 uint8_t valid; 554 uint32_t dev_type; 555 uint8_t channel; 556 uint8_t is_rx; 557 558 // loop on PIC inputs 559 for( id = 0 ; id < CONFIG_MAX_IRQS_PER_PIC ; id++ ) 483 base = dev_tbl[i].base; 484 impl = IMPL_FROM_TYPE( dev_tbl[i].type ); 485 found = true; 486 break; 487 } 488 } 489 490 assert( found , __FUNCTION__ , "PIC device not found\n" ); 491 492 // allocate and initialize the PIC chdev in local cluster 493 chdev = chdev_create( func, 494 impl, 495 0, // channel 496 0, // direction, 497 base ); 498 499 assert( (chdev != NULL), __FUNCTION__ , "no memory for PIC chdev\n" ); 500 501 // make PIC device type specific initialisation 502 dev_pic_init( chdev ); 503 504 // register extended pointer on PIC chdev in "chdev_dir" array in all clusters 505 xptr_t * entry = &chdev_dir.pic; 506 507 for( x = 0 ; x < info->x_size ; x++ ) 508 { 509 for( y = 0 ; y < info->y_size ; y++ ) 510 { 511 cxy_t cxy = (x<<info->y_width) + y; 512 hal_remote_swd( XPTR( cxy , entry ) , 513 XPTR( local_cxy , chdev ) ); 514 } 515 } 516 517 // initialize the "iopic_input" structure 518 // defining how external IRQs are connected to IOPIC 519 uint32_t id; 520 uint8_t valid; 521 uint32_t type; 522 uint8_t channel; 523 uint8_t is_rx; 524 525 for( id = 0 ; id < CONFIG_MAX_EXTERNAL_IRQS ; id++ ) 526 { 527 valid = dev_tbl[i].irq[id].valid; 528 type = dev_tbl[i].irq[id].dev_type; 529 channel = dev_tbl[i].irq[id].channel; 530 is_rx = dev_tbl[i].irq[id].is_rx; 531 532 if( valid ) // only valid inputs are registered 533 { 534 uint32_t * index; // local pointer on one entry 535 uint16_t func = FUNC_FROM_TYPE( type ); 536 537 if ( func == DEV_FUNC_TXT ) 538 index = &iopic_input.txt[channel]; 539 else if( func == DEV_FUNC_IOC ) 540 index = &iopic_input.ioc[channel]; 541 else if( (func == DEV_FUNC_NIC) && (is_rx == 0) ) 542 index = &iopic_input.nic_tx[channel]; 543 else if( (func == DEV_FUNC_NIC) && (is_rx != 0) ) 544 index = &iopic_input.nic_rx[channel]; 545 else if( func == DEV_FUNC_IOB ) 546 index = &iopic_input.iob; 547 else 548 assert( false , __FUNCTION__ , "illegal source device for IOPIC input" ); 549 550 // set entry in local structure 551 *index = id; 552 } 553 } 554 555 kinit_dmsg("\n[INFO] %s created IOPIC chdev in cluster %x at cycle %d\n", 556 __FUNCTION__ , local_cxy , (uint32_t)hal_time_stamp() ); 557 558 } // end iopic_init() 559 560 /////////////////////////////////////////////////////////////////////////////////////////// 561 // This function is called by all CP0s in all cluster to complete the PIC device 562 // initialisation, namely the informations attached to the LAPIC controller. 563 // This initialisation must be done after the IOPIC initialisation, but before other 564 // devices initialisation because the IRQ routing infrastructure is required for both 565 // internal and external devices initialisation. 566 /////////////////////////////////////////////////////////////////////////////////////////// 567 // @ info : pointer on the local boot-info structure. 568 /////////////////////////////////////////////////////////////////////////////////////////// 569 static void lapic_init( boot_info_t * info ) 570 { 571 boot_device_t * dev_tbl; // pointer on boot_info internal devices array 572 uint32_t dev_nr; // number of internal devices 573 uint32_t i; // device index in dev_tbl 574 xptr_t base; // remote pointer on segment base 575 uint32_t func; // device functionnal type in boot_info 576 bool_t found; // LAPIC found 577 578 // get number of internal peripherals and base 579 dev_nr = info->int_dev_nr; 580 dev_tbl = info->int_dev; 581 582 // loop on internal peripherals to get the lapic device 583 for( i = 0 , found = false ; i < dev_nr ; i++ ) 584 { 585 func = FUNC_FROM_TYPE( dev_tbl[i].type ); 586 587 if( func == DEV_FUNC_ICU ) 588 { 589 base = dev_tbl[i].base; 590 found = true; 591 break; 592 } 593 } 594 595 // if the LAPIC controller is not defined in the boot_info, 596 // we simply don't initialize the PIC extensions in the kernel, 597 // making the assumption that the LAPIC related informations 598 // are hidden in the hardware specific PIC driver. 599 if( found ) 600 { 601 // initialise the PIC extensions for 602 // the core descriptor and core manager extensions 603 dev_pic_extend_init( (uint32_t *)GET_PTR( base ) ); 604 605 // initialize the "lapic_input" structure 606 // defining how internal IRQs are connected to LAPIC 607 uint32_t id; 608 uint8_t valid; 609 uint8_t channel; 610 uint32_t func; 611 612 for( id = 0 ; id < CONFIG_MAX_INTERNAL_IRQS ; id++ ) 613 { 614 valid = dev_tbl[i].irq[id].valid; 615 func = FUNC_FROM_TYPE( dev_tbl[i].irq[id].dev_type ); 616 channel = dev_tbl[i].irq[id].channel; 617 618 if( valid ) // only valid local IRQs are registered 560 619 { 561 valid = dev_tbl[i].irq[id].valid; 562 dev_type = dev_tbl[i].irq[id].dev_type; 563 channel = dev_tbl[i].irq[id].channel; 564 is_rx = dev_tbl[i].irq[id].is_rx; 565 566 if( valid ) // only valid inputs are registered 567 { 568 uint32_t * index; // local pointer on one entry 569 uint16_t dev_func = FUNC_FROM_TYPE( dev_type ); 570 571 if( dev_func == DEV_FUNC_TXT ) 572 { 573 index = &chdev_pic_input.txt[channel]; 574 } 575 else if( dev_func == DEV_FUNC_IOC ) 576 { 577 index = &chdev_pic_input.ioc[channel]; 578 } 579 else if( (dev_func == DEV_FUNC_NIC) && (is_rx == 0) ) 580 { 581 index = &chdev_pic_input.nic_tx[channel]; 582 } 583 else if( (dev_func == DEV_FUNC_NIC) && (is_rx != 0) ) 584 { 585 index = &chdev_pic_input.nic_rx[channel]; 586 } 587 else 588 { 589 assert( false , __FUNCTION__ , "illegal source device for PIC input" ); 590 } 591 592 // set entry in local structure 593 *index = id; 594 } 595 } // end loop on PIC inputs 596 } // end PIC 597 } // end loop on devices 598 } // end external_devices_init() 599 620 if ( func == DEV_FUNC_MMC ) lapic_input.mmc = id; 621 else if( func == DEV_FUNC_DMA ) lapic_input.dma[channel] = id; 622 else assert( false , __FUNCTION__ , "illegal source device for LAPIC input" ); 623 } 624 } 625 } 626 } // end lapic_init() 600 627 601 628 /////////////////////////////////////////////////////////////////////////////////////////// … … 645 672 void kernel_init( boot_info_t * info ) 646 673 { 647 lid_t core_lid = -1; // running core local index 648 cxy_t core_cxy = -1; // running core cluster identifier 649 gid_t core_gid; // running core hardware identifier 650 cluster_t * cluster; // pointer on local cluster manager 651 core_t * core; // pointer on running core descriptor 652 thread_t * thread; // pointer on idle thread descriptor 674 lid_t core_lid = -1; // running core local index 675 cxy_t core_cxy = -1; // running core cluster identifier 676 gid_t core_gid; // running core hardware identifier 677 cluster_t * cluster; // pointer on local cluster manager 678 core_t * core; // pointer on running core descriptor 679 thread_t * thread; // pointer on idle thread descriptor 680 xptr_t vfs_root_inode_xp; // extended pointer on VFS root inode 681 // xptr_t devfs_root_inode_xp; // extended pointer on DEVFS root inode 653 682 error_t error; 654 683 655 // all cores get and check core identifiers 684 cxy_t io_cxy = info->io_cxy; 685 686 ///////////////////////////////////////////////////////////////////////////////// 687 // STEP 0 : Each core get its core identifier from boot_info, and makes 688 // a partial initialisation of its private idle thread descriptor. 689 // CP0 initializes the "local_cxy" global variable. 690 // CP0 in cluster IO initializes the TXT0 chdev to print log messages. 691 ///////////////////////////////////////////////////////////////////////////////// 692 656 693 error = get_core_identifiers( info, 657 694 &core_lid, … … 668 705 hal_set_current_thread( thread ); 669 706 707 // each core initializes the idle thread "locks_root" and "xlocks_root" fields 670 708 list_root_init( &thread->locks_root ); 671 xlist_root_init( XPTR( local_cxy, &thread->xlocks_root ) ); 672 673 // CP0 in I/O cluster initializes TXT0 chdev descriptor 674 if( (core_lid == 0) && (core_cxy == info->io_cxy) ) txt0_device_init( info ); 675 676 ///////////////////////////////////////////////////////////////////////////////// 677 // global & local synchro to protect access to TXT0 terminal 678 if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ), 709 xlist_root_init( XPTR( local_cxy , &thread->xlocks_root ) ); 710 711 // CP0 in I/O cluster initialises TXT0 chdev descriptor 712 if( (core_lid == 0) && (core_cxy == io_cxy) ) txt0_device_init( info ); 713 714 ///////////////////////////////////////////////////////////////////////////////// 715 if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ), 679 716 (info->x_size * info->y_size) ); 680 717 barrier_wait( &local_barrier , info->cores_nr ); 681 ///////////////////////////////////////////////////////////////////////////////// 682 683 if( (core_lid == 0) && (local_cxy == info->io_cxy) ) 684 { 685 kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 0 at cycle %d\n", 686 __FUNCTION__ , core_cxy , core_lid , hal_get_cycles() ); 687 } 688 689 // all cores check core identifiers 718 719 if( (core_lid == 0) && (local_cxy == 0) ) 720 kinit_dmsg("\n[INFO] %s exit barrier 0 at cycle %d : TXT0 initialized\n", 721 __FUNCTION__, (uint32_t)hal_time_stamp()); 722 723 ///////////////////////////////////////////////////////////////////////////// 724 // STEP 1 : all cores check its core identifier. 725 // CP0 initializes the local cluster manager. 726 // This includes the memory allocators. 727 ///////////////////////////////////////////////////////////////////////////// 728 729 // all cores check identifiers 690 730 if( error ) 691 731 { … … 696 736 } 697 737 698 // CP0 initializes the local cluster manager (cores and memory allocators)738 // CP0 initializes cluster manager 699 739 if( core_lid == 0 ) 700 740 { … … 703 743 if( error ) 704 744 { 705 nolock_printk("\n[PANIC] in %s : cannot initialise cluster manager in cluster%x",745 nolock_printk("\n[PANIC] in %s : cannot initialise cluster %x", 706 746 __FUNCTION__ , local_cxy ); 707 747 hal_core_sleep(); … … 710 750 711 751 ///////////////////////////////////////////////////////////////////////////////// 712 // global & local synchro, to protect access to cluster manager 713 if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ), 752 if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ), 714 753 (info->x_size * info->y_size) ); 715 754 barrier_wait( &local_barrier , info->cores_nr ); 716 755 ///////////////////////////////////////////////////////////////////////////////// 717 756 718 if( (core_lid == 0) && (local_cxy == info->io_cxy) ) 719 { 720 kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 1 at cycle %d\n", 721 __FUNCTION__ , core_cxy , core_lid , hal_get_cycles() ); 722 } 723 724 // all cores get pointer on local cluster manager and on core descriptor 757 if( (core_lid == 0) && (local_cxy == 0) ) 758 kinit_dmsg("\n[INFO] %s exit barrier 1 at cycle %d : clusters initialised\n", 759 __FUNCTION__, (uint32_t)hal_time_stamp()); 760 761 ///////////////////////////////////////////////////////////////////////////////// 762 // STEP 2 : all CP0s initialize the process_zero descriptor. 763 // CP0 in cluster 0 initialises the IOPIC device. 764 // all CP0s complete the distibuted LAPIC initialization. 765 ///////////////////////////////////////////////////////////////////////////////// 766 767 // all cores get pointer on local cluster manager & core descriptor 725 768 cluster = &cluster_manager; 726 769 core = &cluster->core_tbl[core_lid]; 727 770 728 // CP0 initializesthe process_zero descriptor771 // all CP0s initialize the process_zero descriptor 729 772 if( core_lid == 0 ) process_reference_init( &process_zero , 0 , XPTR_NULL ); 730 773 731 #ifdef __HAL_x86_64__ 732 return; /* XXX temporary */ 733 #endif 734 735 // CP0 allocates and initializes the internal peripheral chdev descriptors. 736 // Each CP0[cxy] scan the set of its internal (private) peripherals, 774 // CP0 in cluster 0 initializes the PIC chdev, 775 if( (core_lid == 0) && (local_cxy == 0) ) iopic_init( info ); 776 777 // all CP0s initialize their local LAPIC extension, 778 if( core_lid == 0 ) lapic_init( info ); 779 780 //////////////////////////////////////////////////////////////////////////////// 781 if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ), 782 (info->x_size * info->y_size) ); 783 barrier_wait( &local_barrier , info->cores_nr ); 784 //////////////////////////////////////////////////////////////////////////////// 785 786 if( (core_lid == 0) && (local_cxy == 0) ) 787 kinit_dmsg("\n[INFO] %s exit barrier 2 at cycle %d : PIC initialised\n", 788 __FUNCTION__, (uint32_t)hal_time_stamp()); 789 790 //////////////////////////////////////////////////////////////////////////////// 791 // STEP 3 : all CP0s initialize their local chdev descriptors 792 // (both internal devices and external devices). 793 //////////////////////////////////////////////////////////////////////////////// 794 795 // CP0 scan the internal (private) peripherals, 737 796 // and allocates memory for the corresponding chdev descriptors. 738 797 if( core_lid == 0 ) internal_devices_init( info ); 739 740 // CP0 allocates one WTI mailbox per core for Inter Processor Interrupt 741 // this must be done after ICU chdev initialisation, by CP0 only, and before 742 // external devices initialisation to enforce the rule : 743 // "The WTI index for the IPI routed to core[lid] is lid" 744 if( core_lid == 1 ) 745 { 746 uint32_t wti_id; 747 uint32_t lid; 748 for( lid = 0 ; lid < LOCAL_CLUSTER->cores_nr ; lid++ ) 749 { 750 wti_id = dev_icu_wti_alloc(); 751 752 if( wti_id != lid ) 753 { 754 nolock_printk("\n[PANIC] in %s : WTI index for IPI = %d / core_lid = %d", 755 __FUNCTION__ , wti_id , lid ); 756 hal_core_sleep(); 757 } 758 759 dev_icu_enable_irq( lid , WTI_TYPE , wti_id , NULL ); 760 } 761 } 798 762 799 763 800 // All CP0s contribute to initialise external peripheral chdev descriptors. … … 765 802 // and allocates memory for the chdev descriptors that must be placed 766 803 // on the (cxy) cluster according to the global index value. 804 767 805 if( core_lid == 0 ) external_devices_init( info ); 768 806 769 807 ///////////////////////////////////////////////////////////////////////////////// 770 // global &local synchro to protect access to peripherals 771 if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ), 808 if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ), 772 809 (info->x_size * info->y_size) ); 773 810 barrier_wait( &local_barrier , info->cores_nr ); 774 811 ///////////////////////////////////////////////////////////////////////////////// 775 812 776 if( (core_lid == 0) && (local_cxy == info->io_cxy) ) 777 { 778 kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 2 at cycle %d\n", 779 __FUNCTION__ , core_cxy , core_lid , hal_get_cycles() ); 780 } 781 813 if( (core_lid == 0) && (local_cxy == 0) ) 814 kinit_dmsg("\n[INFO] %s exit barrier 3 at cycle %d : all chdev initialised\n", 815 __FUNCTION__, (uint32_t)hal_time_stamp()); 816 817 ///////////////////////////////////////////////////////////////////////////////// 818 // STEP 4 : Alls cores initialize their private IDLE thread. 819 // Only CP0 in cluster 0 creates the VFS root inode. 820 // It access the boot device to initialize the file system context. 821 ///////////////////////////////////////////////////////////////////////////////// 822 823 // all cores create idle thread descriptor 782 824 error = thread_kernel_init( thread, 783 825 THREAD_IDLE, … … 792 834 } 793 835 794 // register idle thread in scheduler836 // all cores register idle thread in scheduler 795 837 core->scheduler.idle = thread; 796 838 797 // a ctivate the idle thread839 // all core activate the idle thread 798 840 thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL ); 799 841 800 if( (core_lid == 0) && (local_cxy == info->io_cxy) ) 801 { 802 kinit_dmsg("\n[INFO] %s : core[%x][%d] created idle thread %x at cycle %d\n", 803 __FUNCTION__ , core_cxy , core_lid , thread , hal_get_cycles()); 804 } 805 806 // CP0 in all clusters initializes cooperatively VFS and DEVFS 807 if( (core_lid == 0) ) 808 { 809 xptr_t root_inode_xp; 810 811 // initialize root File System (must be FATFS in this implementation) 842 if( (core_lid == 0) && (local_cxy == 0) ) 843 { 844 kinit_dmsg("\n[INFO] %s : created idle thread %x at cycle %d\n", 845 __FUNCTION__ , thread , (uint32_t)hal_time_stamp()); 846 } 847 848 // CPO in cluster 0 creates the VFS root 849 if( (core_lid == 0) && (local_cxy == 0 ) ) 850 { 851 vfs_root_inode_xp = XPTR_NULL; 852 853 // File System must be FATFS in this implementation, 854 // but other File System can be introduced here 812 855 if( CONFIG_VFS_ROOT_IS_FATFS ) 813 856 { 814 root_inode_xp = fatfs_init(); 857 // 1. create FATFS context in cluster 0 858 fatfs_ctx_t * fatfs_ctx = fatfs_ctx_alloc(); 859 860 nolock_assert( (fatfs_ctx != NULL) , __FUNCTION__ , 861 "cannot create FATFS context in cluster 0\n" ); 862 863 // 2. access boot device to initialize FATFS context 864 fatfs_ctx_init( fatfs_ctx ); 865 866 // 3. get various informations from FATFS context 867 uint32_t root_dir_cluster = fatfs_ctx->root_dir_cluster; 868 uint32_t cluster_size = fatfs_ctx->bytes_per_sector * 869 fatfs_ctx->sectors_per_cluster; 870 uint32_t total_clusters = fatfs_ctx->fat_sectors_count << 7; 871 872 // 4. create VFS root inode in cluster 0 873 error = vfs_inode_create( XPTR_NULL, // dentry_xp 874 FS_TYPE_FATFS, // fs_type 875 INODE_TYPE_DIR, // inode_type 876 (void *)(intptr_t)root_dir_cluster, // extend 877 0, // attr 878 0, // rights 879 0, // uid 880 0, // gid 881 &vfs_root_inode_xp ); // return 882 883 nolock_assert( (error == 0) , __FUNCTION__ , 884 "cannot create VFS root inode\n" ); 885 886 // 5. initialize VFS context for FAT in cluster 0 887 vfs_ctx_init( FS_TYPE_FATFS, // file system type 888 0, // attributes 889 total_clusters, 890 cluster_size, 891 vfs_root_inode_xp, // VFS root 892 fatfs_ctx ); // extend 815 893 } 816 894 else … … 820 898 } 821 899 822 if( root_inode_xp == XPTR_NULL )823 {824 nolock_printk("\n[PANIC] in %s : core[%x][%d] cannot initialize file system\n",825 __FUNCTION__ , local_cxy , core_lid );826 hal_core_sleep();827 }828 829 900 // register VFS root inode in process_zero 830 process_zero.vfs_root_xp = root_inode_xp; 831 process_zero.vfs_cwd_xp = root_inode_xp; 832 833 // mount the DEVFS File system 834 devfs_mount( root_inode_xp , "dev" ); 835 } 836 837 838 // CP0 in I/O cluster creates the process_init and print banner 839 if( (core_lid == 0) && (local_cxy == info->io_cxy) ) 901 process_zero.vfs_root_xp = vfs_root_inode_xp; 902 process_zero.vfs_cwd_xp = vfs_root_inode_xp; 903 } 904 905 ///////////////////////////////////////////////////////////////////////////////// 906 if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ), 907 (info->x_size * info->y_size) ); 908 barrier_wait( &local_barrier , info->cores_nr ); 909 ///////////////////////////////////////////////////////////////////////////////// 910 911 if( (core_lid == 0) && (local_cxy == 0) ) 912 kinit_dmsg("\n[INFO] %s exit barrier 4 at cycle %d : VFS OK in cluster 0\n", 913 __FUNCTION__, (uint32_t)hal_time_stamp()); 914 915 ///////////////////////////////////////////////////////////////////////////////// 916 // STEP 5 : Other CP0s allocate memory for the selected FS context, 917 // and initialise both the local FS context and the local VFS context 918 // from values stored in cluster 0. 919 // They get the VFS root inode extended pointer from cluster 0. 920 ///////////////////////////////////////////////////////////////////////////////// 921 922 if( (core_lid == 0) && (local_cxy != 0) ) 923 { 924 // File System must be FATFS in this implementation, 925 // but other File System can be introduced here 926 if( CONFIG_VFS_ROOT_IS_FATFS ) 927 { 928 // allocate memory for FATFS context 929 fatfs_ctx_t * fatfs_ctx = fatfs_ctx_alloc(); 930 931 nolock_assert( (fatfs_ctx != NULL) , __FUNCTION__ , 932 "cannot create FATFS context\n" ); 933 934 // get local pointer on VFS context for FATFS 935 vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS]; 936 937 // copy VFS context from cluster 0 to local cluster 938 hal_remote_memcpy( XPTR( local_cxy , vfs_ctx ), 939 XPTR( 0 , vfs_ctx ), 940 sizeof(vfs_ctx_t) ); 941 942 // copy FATFS context from cluster 0 to local cluster 943 hal_remote_memcpy( XPTR( local_cxy , fatfs_ctx ), 944 XPTR( 0 , fatfs_ctx ), 945 sizeof(fatfs_ctx_t) ); 946 947 // update extend field in local copy of VFS context 948 vfs_ctx->extend = fatfs_ctx; 949 } 950 951 // get extended pointer on VFS root inode from cluster 0 952 vfs_root_inode_xp = hal_remote_lwd( XPTR( 0 , process_zero.vfs_root_xp ) ); 953 954 // update local process_zero descriptor 955 process_zero.vfs_root_xp = vfs_root_inode_xp; 956 process_zero.vfs_cwd_xp = vfs_root_inode_xp; 957 } 958 959 ///////////////////////////////////////////////////////////////////////////////// 960 // global &local synchro to protect File System initialisation 961 if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ), 962 (info->x_size * info->y_size) ); 963 barrier_wait( &local_barrier , info->cores_nr ); 964 965 if( (core_lid == 0) && (local_cxy == 0) ) 966 kinit_dmsg("\n[INFO] %s exit barrier 5 at cycle %d : VFS OK in all clusters\n", 967 __FUNCTION__, (uint32_t)hal_time_stamp()); 968 969 970 ///////////////////////////////////////////////////////////////////////////////// 971 // STEP 6 : CP0 in cluster IO makes the global DEVFS tree initialisation: 972 // It creates the DEVFS root directory and the DEVFS "external" 973 // diretory in cluster IO and mount these inodes into VFS. 974 ///////////////////////////////////////////////////////////////////////////////// 975 976 if( (core_lid == 0) && (local_cxy == io_cxy) ) 977 { 978 xptr_t devfs_root_inode_xp; // extended pointer on DEVFS root directory 979 xptr_t devfs_external_inode_xp; // extended pointer on DEVFS external directory 980 981 // create "dev" and "external" directories. 982 devfs_global_init( process_zero.vfs_root_xp, 983 &devfs_root_inode_xp, 984 &devfs_external_inode_xp ); 985 986 // creates the DEVFS context in cluster IO 987 devfs_ctx_t * devfs_ctx = devfs_ctx_alloc(); 988 989 nolock_assert( (devfs_ctx != NULL) , __FUNCTION__ , 990 "cannot create DEVFS context in cluster IO\n"); 991 992 // register DEVFS root and external directories 993 devfs_ctx_init( devfs_ctx, devfs_root_inode_xp, devfs_external_inode_xp ); 994 } 995 996 ///////////////////////////////////////////////////////////////////////////////// 997 // global &local synchro to protect File System initialisation 998 if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ), 999 (info->x_size * info->y_size) ); 1000 barrier_wait( &local_barrier , info->cores_nr ); 1001 1002 if( (core_lid == 0) && (local_cxy == 0) ) 1003 kinit_dmsg("\n[INFO] %s exit barrier 6 at cycle %d : DEVFS OK in cluster IO\n", 1004 __FUNCTION__, (uint32_t)hal_time_stamp()); 1005 1006 ///////////////////////////////////////////////////////////////////////////////// 1007 // STEP 7 : All CP0s complete in parallel the DEVFS tree initialization. 1008 // Each CP0 get the "dev" and "external" extended pointers from 1009 // values storred in cluster IO. Then CP0 in cluster(i) creates the 1010 // DEVFS "internal directory, and creates the pseudo-files for all 1011 // chdevs contained in cluster (i). 1012 ///////////////////////////////////////////////////////////////////////////////// 1013 1014 if( core_lid == 0 ) 1015 { 1016 xptr_t root_inode_xp; // extended pointer on DEVFS root directory 1017 xptr_t external_inode_xp; // extended pointer on DEVFS external directory 1018 1019 // get extended pointer on "extend" field of VFS context for DEVFS in cluster IO 1020 xptr_t extend_xp = XPTR( io_cxy , &fs_context[FS_TYPE_DEVFS].extend ); 1021 1022 // get pointer on DEVFS context in cluster IO 1023 devfs_ctx_t * devfs_ctx = hal_remote_lpt( extend_xp ); 1024 1025 root_inode_xp = hal_remote_lwd( XPTR( io_cxy , &devfs_ctx->root_inode_xp ) ); 1026 external_inode_xp = hal_remote_lwd( XPTR( io_cxy , &devfs_ctx->external_inode_xp ) ); 1027 1028 devfs_local_init( root_inode_xp, 1029 external_inode_xp ); 1030 } 1031 1032 ///////////////////////////////////////////////////////////////////////////////// 1033 // global &local synchro to protect File System initialisation 1034 if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ), 1035 (info->x_size * info->y_size) ); 1036 barrier_wait( &local_barrier , info->cores_nr ); 1037 1038 if( (core_lid == 0) && (local_cxy == 0) ) 1039 kinit_dmsg("\n[INFO] %s exit barrier 7 at cycle %d : DEVFS OK in all clusters\n", 1040 __FUNCTION__, (uint32_t)hal_time_stamp()); 1041 1042 ///////////////////////////////////////////////////////////////////////////////// 1043 // STEP 8 : CP0 in I/O cluster creates the process_init and print banner. 1044 ///////////////////////////////////////////////////////////////////////////////// 1045 1046 if( (core_lid == 0) && (local_cxy == io_cxy) ) 840 1047 { 841 1048 process_init_create(); 842 1049 } 1050 1051 ///////////////////////////////////////////////////////////////////////////////// 1052 // global syncho to protect access to File System 1053 if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ), 1054 (info->x_size * info->y_size) ); 1055 barrier_wait( &local_barrier , info->cores_nr ); 1056 1057 if( (core_lid == 0) && (local_cxy == 0) ) 1058 kinit_dmsg("\n[INFO] %s exit barrier 8 at cycle %d : process init created\n", 1059 __FUNCTION__ , (uint32_t)hal_time_stamp() ); 1060 1061 ///////////////////////////////////////////////////////////////////////////////// 1062 // STEP 9 : CP0 in cluster 0 print banner 1063 ///////////////////////////////////////////////////////////////////////////////// 1064 1065 if( (core_lid == 0) && (local_cxy == io_cxy) ) 1066 { 843 1067 print_banner( (info->x_size * info->y_size) , info->cores_nr ); 844 1068 … … 886 1110 } 887 1111 888 /////////////////////////////////////////////////////////////////////////////////889 // global syncho to protect access to File System890 if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ),891 (info->x_size * info->y_size) );892 barrier_wait( &local_barrier , info->cores_nr );893 /////////////////////////////////////////////////////////////////////////////////894 895 if( (core_lid == 0) && (local_cxy == info->io_cxy) )896 {897 kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 3 at cycle %d\n",898 __FUNCTION__ , core_cxy , core_lid , hal_get_cycles() );899 }900 901 1112 // each core activates its private PTI IRQ 902 dev_icu_set_period( core_lid , CONFIG_SCHED_TICK_PERIOD ); 903 dev_icu_enable_irq( core_lid , PTI_TYPE , core_lid , NULL ); 904 905 // each core get its private IRQ masks values 906 uint32_t hwi_mask; 907 uint32_t wti_mask; 908 uint32_t pti_mask; 909 dev_icu_get_masks( core_lid , &hwi_mask , &wti_mask , &pti_mask ); 910 911 thread_dmsg("\n[INFO] %s : core[%x][%d] complete kernel init at cycle %d\n" 912 " hwi_mask = %x / wti_mask = %x / pti_mask = %x\n", 913 __FUNCTION__ , local_cxy , core_lid , hal_get_cycles() , 914 hwi_mask , wti_mask , pti_mask ); 1113 dev_pic_enable_timer( CONFIG_SCHED_TICK_PERIOD ); 1114 1115 if( (core_lid == 0) && (local_cxy == io_cxy) ) 1116 thread_dmsg("\n[INFO] %s complete kernel init in cluster 0 at cycle %d\n" 1117 __FUNCTION__ , (uint32_t)hal_time_stamp() ) 915 1118 916 1119 // each core jump to idle thread
Note: See TracChangeset
for help on using the changeset viewer.