int __init arch_smp_prepare_cpus(unsigned int max_cpus) { int i, rc; physical_addr_t _start_secondary_pa; /* Get physical address secondary startup code */ rc = vmm_host_va2pa((virtual_addr_t)&_start_secondary, &_start_secondary_pa); if (rc) { return rc; } /* Update the cpu_present bitmap */ for (i = 0; i < max_cpus; i++) { vmm_set_cpu_present(i, TRUE); } if (scu_base) { /* Enable snooping through SCU */ scu_enable((void *)scu_base); } if (pmu_base) { /* Write the entry address for the secondary cpus */ vmm_writel((u32)_start_secondary_pa, (void *)pmu_base + 0x814); } return VMM_OK; }
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(); }