/* Boot the current CPU */ void __cpuinit start_secondary(unsigned long boot_phys_offset, unsigned long fdt_paddr, unsigned long hwid) { unsigned int cpuid = init_data.cpuid; memset(get_cpu_info(), 0, sizeof (struct cpu_info)); set_processor_id(cpuid); current_cpu_data = boot_cpu_data; identify_cpu(¤t_cpu_data); init_traps(); setup_virt_paging(); mmu_init_secondary_cpu(); gic_init_secondary_cpu(); init_secondary_IRQ(); gic_route_ppis(); init_maintenance_interrupt(); init_timer_interrupt(); set_current(idle_vcpu[cpuid]); setup_cpu_sibling_map(cpuid); /* Run local notifiers */ notify_cpu_starting(cpuid); wmb(); /* Now report this CPU is up */ smp_up_cpu = MPIDR_INVALID; cpumask_set_cpu(cpuid, &cpu_online_map); wmb(); local_irq_enable(); local_abort_enable(); printk(XENLOG_DEBUG "CPU %u booted.\n", smp_processor_id()); startup_cpu_idle_loop(); }
/* Boot the current CPU */ void __cpuinit start_secondary(unsigned long boot_phys_offset, unsigned long fdt_paddr, unsigned long cpuid) { struct cpuinfo_arm *c = cpu_data + cpuid; memset(get_cpu_info(), 0, sizeof (struct cpu_info)); /* TODO: handle boards where CPUIDs are not contiguous */ set_processor_id(cpuid); *c = boot_cpu_data; identify_cpu(c); /* Setup Hyp vector base */ WRITE_SYSREG((vaddr_t)hyp_traps_vector, VBAR_EL2); mmu_init_secondary_cpu(); enable_vfp(); gic_init_secondary_cpu(); init_secondary_IRQ(); gic_route_ppis(); init_maintenance_interrupt(); init_timer_interrupt(); set_current(idle_vcpu[cpuid]); setup_cpu_sibling_map(cpuid); /* Run local notifiers */ notify_cpu_starting(cpuid); wmb(); /* Now report this CPU is up */ cpumask_set_cpu(cpuid, &cpu_online_map); wmb(); local_irq_enable(); dprintk(XENLOG_DEBUG, "CPU %u booted.\n", smp_processor_id()); startup_cpu_idle_loop(); }
/* C entry point for boot CPU */ void __init start_xen(unsigned long boot_phys_offset, unsigned long fdt_paddr, unsigned long cpuid) { size_t fdt_size; int cpus, i; const char *cmdline; setup_cache(); percpu_init_areas(); set_processor_id(0); /* needed early, for smp_processor_id() */ smp_clear_cpu_maps(); /* This is mapped by head.S */ device_tree_flattened = (void *)BOOT_FDT_VIRT_START + (fdt_paddr & ((1 << SECOND_SHIFT) - 1)); fdt_size = device_tree_early_init(device_tree_flattened, fdt_paddr); cmdline = device_tree_bootargs(device_tree_flattened); early_printk("Command line: %s\n", cmdline); cmdline_parse(cmdline); setup_pagetables(boot_phys_offset, get_xen_paddr()); setup_mm(fdt_paddr, fdt_size); vm_init(); dt_unflatten_host_device_tree(); dt_irq_xlate = gic_irq_xlate; dt_uart_init(); console_init_preirq(); system_state = SYS_STATE_boot; processor_id(); platform_init(); smp_init_cpus(); cpus = smp_get_max_cpus(); init_xen_time(); gic_init(); set_current((struct vcpu *)0xfffff000); /* debug sanity */ idle_vcpu[0] = current; init_traps(); setup_virt_paging(); p2m_vmid_allocator_init(); softirq_init(); tasklet_subsys_init(); init_IRQ(); gic_route_ppis(); gic_route_spis(); init_maintenance_interrupt(); init_timer_interrupt(); timer_init(); init_idle_domain(); rcu_init(); arch_init_memory(); local_irq_enable(); local_abort_enable(); smp_prepare_cpus(cpus); initialize_keytable(); console_init_postirq(); do_presmp_initcalls(); for_each_present_cpu ( i ) { if ( (num_online_cpus() < cpus) && !cpu_online(i) ) { int ret = cpu_up(i); if ( ret != 0 ) printk("Failed to bring up CPU %u (error %d)\n", i, ret); } } printk("Brought up %ld CPUs\n", (long)num_online_cpus()); /* TODO: smp_cpus_done(); */ do_initcalls(); /* Create initial domain 0. */ dom0 = domain_create(0, 0, 0); if ( IS_ERR(dom0) || (alloc_dom0_vcpu0() == NULL) ) panic("Error creating domain 0"); dom0->is_privileged = 1; dom0->target = NULL; if ( construct_dom0(dom0) != 0) panic("Could not set up DOM0 guest OS"); /* Scrub RAM that is still free and so may go to an unprivileged domain. */ scrub_heap_pages(); init_constructors(); console_endboot(); /* Hide UART from DOM0 if we're using it */ serial_endboot(); system_state = SYS_STATE_active; domain_unpause_by_systemcontroller(dom0); /* Switch on to the dynamically allocated stack for the idle vcpu * since the static one we're running on is about to be freed. */ memcpy(idle_vcpu[0]->arch.cpu_info, get_cpu_info(), sizeof(struct cpu_info)); switch_stack_and_jump(idle_vcpu[0]->arch.cpu_info, init_done); }