예제 #1
0
파일: partition.c 프로젝트: UPD-RTS/TiCOS
/**
 * \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;
}
예제 #2
0
파일: partition.c 프로젝트: p-vlasov/pok
/**
 * \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;
}