Esempio n. 1
0
int __init arch_smp_prepare_cpus(void)
{
	int rc = VMM_OK;
	struct vmm_devtree_node *node;
	virtual_addr_t ca9_scu_base;
	u32 ncores;
	int i;

	/* Get the SCU node in the dev tree */
	node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING
				   VMM_DEVTREE_HOSTINFO_NODE_NAME
				   VMM_DEVTREE_PATH_SEPARATOR_STRING "scu");
	if (!node) {
		return VMM_EFAIL;
	}

	/* map the SCU physical address to virtual address */
	rc = vmm_devtree_regmap(node, &ca9_scu_base, 0);
	if (rc) {
		return rc;
	}

	/* How many ARM core do we have */
	ncores = scu_get_core_count((void *)ca9_scu_base);

	/* Find out the number of SMP-enabled cpu cores */
	for (i = 0; i < CONFIG_CPU_COUNT; i++) {
		/* build the possible CPU map */
		if ((i >= ncores)
		    || !scu_cpu_core_is_smp((void *)ca9_scu_base, i)) {
			/* Update the cpu_possible bitmap */
			vmm_set_cpu_possible(i, 0);
		} else {
			vmm_set_cpu_possible(i, 1);
		}
	}

	/* Enable snooping through SCU */
	scu_enable((void *)ca9_scu_base);

	/* unmap the SCU node */
	rc = vmm_devtree_regunmap(node, ca9_scu_base, 0);

	return rc;
}
Esempio n. 2
0
int __init arch_smp_init_cpus(void)
{
	u32 ncores;
	int i, rc = VMM_OK;
	struct vmm_devtree_node *node;

	/* Get the PMU node in the dev tree */
	node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING "pmu");
	if (!node) {
		return VMM_EFAIL;
	}

	/* Map the PMU physical address to virtual address */
	rc = vmm_devtree_regmap(node, &pmu_base, 0);
	if (rc) {
		return rc;
	}

	/* Get the SCU node in the dev tree */
	node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING "scu");
	if (!node) {
		return VMM_EFAIL;
	}

	/* Map the SCU physical address to virtual address */
	rc = vmm_devtree_regmap(node, &scu_base, 0);
	if (rc) {
		return rc;
	}

	/* How many ARM core do we have */
	ncores = scu_get_core_count((void *)scu_base);

	/* Update the cpu_possible bitmap based on SCU */
	for (i = 0; i < CONFIG_CPU_COUNT; i++) {
		if ((i < ncores) &&
		    scu_cpu_core_is_smp((void *)scu_base, i)) {
			vmm_set_cpu_possible(i, TRUE);
		}
	}

	return VMM_OK;
}
Esempio n. 3
0
void vmm_init(void)
{
	int ret;
#if defined(CONFIG_SMP)
	u32 c;
#endif
	u32 cpu = vmm_smp_processor_id();
	struct vmm_work sysinit;

	/* Mark this CPU possible & present */
	vmm_set_cpu_possible(cpu, TRUE);
	vmm_set_cpu_present(cpu, TRUE);

	/* Print version string */
	vmm_printf("\n");
	vmm_printf("%s v%d.%d.%d (%s %s)\n", VMM_NAME, 
		   VMM_VERSION_MAJOR, VMM_VERSION_MINOR, VMM_VERSION_RELEASE,
		   __DATE__, __TIME__);
	vmm_printf("\n");

	/* Initialize host virtual address space */
	vmm_printf("Initialize Host Address Space\n");
	ret = vmm_host_aspace_init();
	if (ret) {
		vmm_hang();
	}

	/* Initialize heap */
	vmm_printf("Initialize Heap Management\n");
	ret = vmm_heap_init();
	if (ret) {
		vmm_hang();
	}

	/* Initialize per-cpu area */
	vmm_printf("Initialize PerCPU Areas\n");
	ret = vmm_percpu_init();
	if (ret) {
		vmm_hang();
	}

	/* Initialize device tree */
	vmm_printf("Initialize Device Tree\n");
	ret = vmm_devtree_init();
	if (ret) {
		vmm_hang();
	}

	/* Initialize host interrupts */
	vmm_printf("Initialize Host IRQ\n");
	ret = vmm_host_irq_init();
	if (ret) {
		vmm_hang();
	}

	/* Initialize CPU early */
	vmm_printf("Initialize CPU Early\n");
	ret = arch_cpu_early_init();
	if (ret) {
		vmm_hang();
	}

	/* Initialize Board early */
	vmm_printf("Initialize Board Early\n");
	ret = arch_board_early_init();
	if (ret) {
		vmm_hang();
	}

	/* Initialize standerd input/output */
	vmm_printf("Initialize Standard I/O\n");
	ret = vmm_stdio_init();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}

	/* Initialize clocksource manager */
	vmm_printf("Initialize Clocksource Manager\n");
	ret = vmm_clocksource_init();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}

	/* Initialize clockchip manager */
	vmm_printf("Initialize Clockchip Manager\n");
	ret = vmm_clockchip_init();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}

	/* Initialize hypervisor timer */
	vmm_printf("Initialize Hypervisor Timer\n");
	ret = vmm_timer_init();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}

	/* Initialize soft delay */
	vmm_printf("Initialize Soft Delay\n");
	ret = vmm_delay_init();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}

	/* Initialize hypervisor manager */
	vmm_printf("Initialize Hypervisor Manager\n");
	ret = vmm_manager_init();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}

	/* Initialize hypervisor scheduler */
	vmm_printf("Initialize Hypervisor Scheduler\n");
	ret = vmm_scheduler_init();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}

	/* Initialize hypervisor threads */
	vmm_printf("Initialize Hypervisor Threads\n");
	ret = vmm_threads_init();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}

#ifdef CONFIG_PROFILE
	/* Intialize hypervisor profiler */
	vmm_printf("Initialize Hypervisor Profiler\n");
	ret = vmm_profiler_init();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}
#endif

#if defined(CONFIG_SMP)
	/* Initialize inter-processor interrupts */
	vmm_printf("Initialize Inter Processor Interrupts\n")
	ret = vmm_smp_ipi_init();
	if (ret) {
		vmm_hang();
	}

	/* Initialize secondary CPUs */
	vmm_printf("Initialize Secondary CPUs\n");
	ret = arch_smp_init_cpus();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}

	/* Prepare secondary CPUs */
	ret = arch_smp_prepare_cpus(vmm_num_possible_cpus());
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}

	/* Start each present secondary CPUs */
	for_each_present_cpu(c) {
		if (c == cpu) {
			continue;
		}
		ret = arch_smp_start_cpu(c);
		if (ret) {
			vmm_printf("Failed to start CPU%d\n", ret);
		}
	}

	/* Initialize hypervisor load balancer */
	vmm_printf("Initialize Hypervisor Load Balancer\n");
	ret = vmm_loadbal_init();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}
#endif

	/* Initialize workqueue framework */
	vmm_printf("Initialize Workqueue Framework\n");
	ret = vmm_workqueue_init();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}

	/* Initialize wallclock */
	vmm_printf("Initialize Wallclock Subsystem\n");
	ret = vmm_wallclock_init();
	if (ret) {
		vmm_panic("Error %d\n", ret);
	}

	/* Schedule system initialization work */
	INIT_WORK(&sysinit, &system_init_work);
	vmm_workqueue_schedule_work(NULL, &sysinit);

	/* Start timer (Must be last step) */
	vmm_timer_start();

	/* Wait here till scheduler gets invoked by timer */
	vmm_hang();
}