/** * \brief Initialize all partitions. * * It initializes everything, load the program, set thread * and lockobjects bounds. */ pok_ret_t pok_partition_init () { uint8_t i; uint32_t threads_index = 0; const uint32_t partition_size[POK_CONFIG_NB_PARTITIONS] = POK_CONFIG_PARTITIONS_SIZE; #if defined (POK_CONFIG_PARTITIONS_LOADADDR) && defined (POK_SKIP_LOADER) const uint32_t program_loadaddr[POK_CONFIG_NB_PARTITIONS] = POK_CONFIG_PARTITIONS_LOADADDR; #endif #ifdef POK_NEEDS_LOCKOBJECTS uint8_t lockobj_index = 0; #endif for (i = 0 ; i < POK_CONFIG_NB_PARTITIONS ; i++) { uint32_t size = partition_size[i]; uint32_t base_addr = (uint32_t)pok_bsp_mem_alloc(partition_size[i]); uint32_t program_entry; uint32_t base_vaddr = pok_space_base_vaddr(base_addr); #if defined (POK_CONFIG_PARTITIONS_LOADADDR) && defined (POK_SKIP_LOADER) // One may want to check that consistent addresses were specified printf ("Partition base addr phys=|%x| (user-defined |%x|)",base_addr, program_loadaddr[i]); #endif pok_partitions[i].base_addr = base_addr; pok_partitions[i].size = size; pok_partitions[i].sched = POK_SCHED_RR; pok_partitions[i].partition_id = i; //#ifdef POK_NEEDS_DEBUG //#include <libc.h> printf ("[XCOV] Partition %d loaded at addr virt=|%x|, phys=|%x|\n", i, base_vaddr, base_addr); //#endif pok_partition_setup_scheduler (i); pok_create_space (i, base_addr, size); pok_partitions[i].base_vaddr = base_vaddr; /* Set the memory space and so on */ pok_partitions[i].thread_index_low = threads_index; pok_partitions[i].nthreads = ((uint32_t[]) POK_CONFIG_PARTITIONS_NTHREADS) [i]; #ifdef POK_NEEDS_ERROR_HANDLING if (pok_partitions[i].nthreads <= 1) { pok_partition_error (i, POK_ERROR_KIND_PARTITION_CONFIGURATION); } #endif #ifdef POK_CONFIG_PARTITIONS_SCHEDULER pok_partitions[i].sched = ((pok_sched_t[]) POK_CONFIG_PARTITIONS_SCHEDULER) [i]; #endif pok_partitions[i].thread_index_high = pok_partitions[i].thread_index_low + ((uint32_t[]) POK_CONFIG_PARTITIONS_NTHREADS) [i]; pok_partitions[i].activation = 0; #ifdef POK_CONFIG_PARTITIONS_PERIOD pok_partitions[i].period = ((uint32_t[]) POK_CONFIG_PARTITIONS_PERIOD[i]); #else pok_partitions[i].period = POK_CONFIG_SCHEDULING_MAJOR_FRAME; #endif pok_partitions[i].thread_index = 0; pok_partitions[i].thread_main = 0; pok_partitions[i].current_thread = IDLE_THREAD; pok_partitions[i].prev_current_thread = IDLE_THREAD; threads_index = threads_index + pok_partitions[i].nthreads; /* Initialize the threading stuff */ pok_partitions[i].mode = POK_PARTITION_MODE_INIT_WARM; #ifdef POK_NEEDS_LOCKOBJECTS pok_partitions[i].lockobj_index_low = lockobj_index; pok_partitions[i].lockobj_index_high = lockobj_index + ((uint8_t[]) POK_CONFIG_PARTITIONS_NLOCKOBJECTS[i]); pok_partitions[i].nlockobjs = ((uint8_t[]) POK_CONFIG_PARTITIONS_NLOCKOBJECTS[i]); lockobj_index = lockobj_index + pok_partitions[i].nlockobjs; #endif #ifdef POK_NEEDS_ERROR_HANDLING pok_partitions[i].thread_error = 0; pok_partitions[i].error_status.failed_thread = 0; pok_partitions[i].error_status.failed_addr = 0; pok_partitions[i].error_status.error_kind = POK_ERROR_KIND_INVALID; pok_partitions[i].error_status.msg_size = 0; #endif #ifdef POK_NEEDS_DEBUG printf("loading partition\n"); #endif /** This invokation worked just because the base_vaddr was always 0 */ //pok_loader_load_partition (i, base_addr - base_vaddr, &program_entry); pok_loader_load_partition (i, base_addr, &program_entry); #ifdef POK_NEEDS_DEBUG printf("\t end loading partition\n"); #endif /* * Load the partition in its address space */ pok_partitions[i].thread_main_entry = program_entry; #ifdef POK_NEEDS_SCHED_O1_SPLIT /* initialize the successors bitmask with all zeros; we set to 1 the bits * corresponding to successor threads when the partition changes its mode to NORMAL. */ pok_partitions[i].successors = 0; /* initialize the executed_predecessors with all 1s; this because a thread that is * not a successor has its bit set to 1 in this bitmask (i.e. it can always execute). * We set to 0 the bits corresponding to successor threads when the partition change * its mode to NORMAL. */ pok_partitions[i].executed_predecessors = 1; /* initialize head and tail indexes of sporadic threads FIFO queue */ pok_partitions[i].head_index = 0; pok_partitions[i].tail_index = -1; /* initialize the FIFO queue; the queue is initialized with all bitmasks corresponding * to the idle thread */ int sporadic_index = 0; for (;sporadic_index<POK_CONFIG_NB_SPORADIC_THREADS;sporadic_index++) { pok_partitions[i].sporadic_ready_queue[sporadic_index] = 1 << (IDLE_THREAD - pok_partitions[i].thread_index_low); } #endif /* end ifdef POK_NEEDS_SCHED_O1_SPLIT */ } // end for for (i = 0 ; i < POK_CONFIG_NB_PARTITIONS ; i++) { pok_partition_setup_main_thread (i); } return POK_ERRNO_OK; }
/** * \brief Initialize all partitions. * * It initializes everything, load the program, set thread * and lockobjects bounds. */ pok_ret_t pok_partition_init () { uint8_t i; uint32_t threads_index = 0; const uint32_t partition_size[POK_CONFIG_NB_PARTITIONS] = POK_CONFIG_PARTITIONS_SIZE; #ifdef POK_CONFIG_PARTITIONS_LOADADDR const uint32_t program_loadaddr[POK_CONFIG_NB_PARTITIONS] = POK_CONFIG_PROGRAM_LOADADDR; #endif #ifdef POK_NEEDS_LOCKOBJECTS uint8_t lockobj_index = 0; #endif for (i = 0 ; i < POK_CONFIG_NB_PARTITIONS ; i++) { uint32_t size = partition_size[i]; #ifndef POK_CONFIG_PARTITIONS_LOADADDR uint32_t base_addr = (uint32_t)pok_bsp_mem_alloc(partition_size[i]); #else uint32_t base_addr = program_loadaddr[i]; #endif uint32_t program_entry; uint32_t base_vaddr = pok_space_base_vaddr(base_addr); pok_partitions[i].base_addr = base_addr; pok_partitions[i].size = size; pok_partitions[i].sched = POK_SCHED_RR; #ifdef POK_NEEDS_COVERAGE_INFOS #include <libc.h> printf ("[XCOV] Partition %d loaded at addr virt=|%x|, phys=|%x|\n", i, base_vaddr, base_addr); #endif pok_partition_setup_scheduler (i); pok_create_space (i, base_addr, size); pok_partitions[i].base_vaddr = base_vaddr; /* Set the memory space and so on */ pok_partitions[i].thread_index_low = threads_index; pok_partitions[i].nthreads = ((uint32_t[]) POK_CONFIG_PARTITIONS_NTHREADS) [i]; #ifdef POK_NEEDS_ERROR_HANDLING if (pok_partitions[i].nthreads <= 1) { pok_partition_error (i, POK_ERROR_KIND_PARTITION_CONFIGURATION); } #endif #ifdef POK_CONFIG_PARTITIONS_SCHEDULER pok_partitions[i].sched = ((pok_sched_t[]) POK_CONFIG_PARTITIONS_SCHEDULER) [i]; #endif pok_partitions[i].thread_index_high = pok_partitions[i].thread_index_low + ((uint32_t[]) POK_CONFIG_PARTITIONS_NTHREADS) [i]; pok_partitions[i].activation = 0; pok_partitions[i].period = 0; pok_partitions[i].thread_index = 0; pok_partitions[i].thread_main = 0; pok_partitions[i].current_thread = IDLE_THREAD; pok_partitions[i].prev_thread = IDLE_THREAD; // breaks the rule of prev_thread not being idle, but it's just for init #ifdef POK_NEEDS_SCHED_HFPPS pok_partitions[i].payback = 0; #endif /* POK_NEEDS_SCHED_HFPPS */ threads_index = threads_index + pok_partitions[i].nthreads; /* Initialize the threading stuff */ pok_partitions[i].mode = POK_PARTITION_MODE_INIT_WARM; #ifdef POK_NEEDS_LOCKOBJECTS pok_partitions[i].lockobj_index_low = lockobj_index; pok_partitions[i].lockobj_index_high = lockobj_index + ((uint8_t[]) POK_CONFIG_PARTITIONS_NLOCKOBJECTS[i]); pok_partitions[i].nlockobjs = ((uint8_t[]) POK_CONFIG_PARTITIONS_NLOCKOBJECTS[i]); lockobj_index = lockobj_index + pok_partitions[i].nlockobjs; /* Initialize mutexes stuff */ #endif #ifdef POK_NEEDS_ERROR_HANDLING pok_partitions[i].thread_error = 0; pok_partitions[i].error_status.failed_thread = 0; pok_partitions[i].error_status.failed_addr = 0; pok_partitions[i].error_status.error_kind = POK_ERROR_KIND_INVALID; pok_partitions[i].error_status.msg_size = 0; #endif pok_loader_load_partition (i, base_addr - base_vaddr, &program_entry); /* * Load the partition in its address space */ pok_partitions[i].thread_main_entry = program_entry; pok_partitions[i].lock_level = 0; pok_partitions[i].start_condition = NORMAL_START; #ifdef POK_NEEDS_INSTRUMENTATION pok_instrumentation_partition_archi (i); #endif pok_partition_setup_main_thread (i); pok_partitions[i].current_thread = pok_partitions[i].thread_main; } return POK_ERRNO_OK; }