コード例 #1
0
ファイル: smp.c プロジェクト: qiqjiao/openrisc
asmlinkage void secondary_start_kernel(void)
{
	struct mm_struct *mm = &init_mm;
	unsigned int cpu = smp_processor_id();
	/*
	 * All kernel threads share the same mm context; grab a
	 * reference and switch to it.
	 */
	atomic_inc(&mm->mm_count);
	current->active_mm = mm;
	cpumask_set_cpu(cpu, mm_cpumask(mm));

	printk("CPU%u: Booted secondary processor\n", cpu);

	setup_cpuinfo();
	openrisc_clockevent_init();

	notify_cpu_starting(cpu);

	/*
	 * OK, now it's safe to let the boot CPU continue
	 */
	set_cpu_online(cpu, true);
	complete(&cpu_running);

	local_irq_enable();

	/*
	 * OK, it's off to the idle thread for us
	 */
	cpu_startup_entry(CPUHP_ONLINE);
}
コード例 #2
0
ファイル: smp.c プロジェクト: garyvan/openwrt-1.6
static void __cpuinit cpu_bringup(void)
{
	int cpu;

	cpu_init();
	touch_softlockup_watchdog();
	preempt_disable();

	xen_enable_sysenter();
	xen_enable_syscall();

	cpu = smp_processor_id();
	smp_store_cpu_info(cpu);
	cpu_data(cpu).x86_max_cores = 1;
	set_cpu_sibling_map(cpu);

	xen_setup_cpu_clockevents();

	notify_cpu_starting(cpu);

	set_cpu_online(cpu, true);

	this_cpu_write(cpu_state, CPU_ONLINE);

	wmb();

	/* We can take interrupts now: we're officially "up". */
	local_irq_enable();

	wmb();			/* make sure everything is out */
}
コード例 #3
0
ファイル: smp_32.c プロジェクト: 0x000000FF/Linux4Edison
void __cpuinit sparc_start_secondary(void *arg)
{
	unsigned int cpu;

	/*
	 * SMP booting is extremely fragile in some architectures. So run
	 * the cpu initialization code first before anything else.
	 */
	arch_cpu_pre_starting(arg);

	preempt_disable();
	cpu = smp_processor_id();

	/* Invoke the CPU_STARTING notifier callbacks */
	notify_cpu_starting(cpu);

	arch_cpu_pre_online(arg);

	/* Set the CPU in the cpu_online_mask */
	set_cpu_online(cpu, true);

	/* Enable local interrupts now */
	local_irq_enable();

	wmb();
	cpu_startup_entry(CPUHP_ONLINE);

	/* We should never reach here! */
	BUG();
}
コード例 #4
0
ファイル: smp.c プロジェクト: mbgg/linux
static void __cpuinit cpu_bringup(void)
{
	int cpu;

	cpu_init();
	touch_softlockup_watchdog();
	preempt_disable();

	/* PVH runs in ring 0 and allows us to do native syscalls. Yay! */
	if (!xen_feature(XENFEAT_supervisor_mode_kernel)) {
		xen_enable_sysenter();
		xen_enable_syscall();
	}
	cpu = smp_processor_id();
	smp_store_cpu_info(cpu);
	cpu_data(cpu).x86_max_cores = 1;
	set_cpu_sibling_map(cpu);

	xen_setup_cpu_clockevents();

	notify_cpu_starting(cpu);

	set_cpu_online(cpu, true);

	this_cpu_write(cpu_state, CPU_ONLINE);

	wmb();

	/* We can take interrupts now: we're officially "up". */
	local_irq_enable();

	wmb();			/* make sure everything is out */
}
コード例 #5
0
ファイル: smpboot.c プロジェクト: fhgwright/bb-linux
/*
 * Bring a secondary processor online.
 */
void online_secondary(void)
{
	/*
	 * low-memory mappings have been cleared, flush them from
	 * the local TLBs too.
	 */
	local_flush_tlb();

	BUG_ON(in_interrupt());

	/* This must be done before setting cpu_online_mask */
	wmb();

	notify_cpu_starting(smp_processor_id());

	set_cpu_online(smp_processor_id(), 1);
	__this_cpu_write(cpu_state, CPU_ONLINE);

	/* Set up tile-specific state for this cpu. */
	setup_cpu(0);

	/* Set up tile-timer clock-event device on this cpu */
	setup_tile_timer();

	cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
コード例 #6
0
ファイル: smp.c プロジェクト: jakev/CobraDroidBeta
/* Activate a secondary processor. */
int __devinit start_secondary(void *unused)
{
	unsigned int cpu = smp_processor_id();
	struct device_node *l2_cache;
	int i, base;

	atomic_inc(&init_mm.mm_count);
	current->active_mm = &init_mm;

	smp_store_cpu_info(cpu);
	set_dec(tb_ticks_per_jiffy);
	preempt_disable();
	cpu_callin_map[cpu] = 1;

	smp_ops->setup_cpu(cpu);
	if (smp_ops->take_timebase)
		smp_ops->take_timebase();

	if (system_state > SYSTEM_BOOTING)
		snapshot_timebase();

	secondary_cpu_time_init();

	ipi_call_lock();
	notify_cpu_starting(cpu);
	cpu_set(cpu, cpu_online_map);
	/* Update sibling maps */
	base = cpu_first_thread_in_core(cpu);
	for (i = 0; i < threads_per_core; i++) {
		if (cpu_is_offline(base + i))
			continue;
		cpu_set(cpu, per_cpu(cpu_sibling_map, base + i));
		cpu_set(base + i, per_cpu(cpu_sibling_map, cpu));

		/* cpu_core_map should be a superset of
		 * cpu_sibling_map even if we don't have cache
		 * information, so update the former here, too.
		 */
		cpu_set(cpu, per_cpu(cpu_core_map, base +i));
		cpu_set(base + i, per_cpu(cpu_core_map, cpu));
	}
	l2_cache = cpu_to_l2cache(cpu);
	for_each_online_cpu(i) {
		struct device_node *np = cpu_to_l2cache(i);
		if (!np)
			continue;
		if (np == l2_cache) {
			cpu_set(cpu, per_cpu(cpu_core_map, i));
			cpu_set(i, per_cpu(cpu_core_map, cpu));
		}
		of_node_put(np);
	}
	of_node_put(l2_cache);
	ipi_call_unlock();

	local_irq_enable();

	cpu_idle();
	return 0;
}
コード例 #7
0
ファイル: smp.c プロジェクト: 1800alex/linux
/*
 * Called by secondaries to update state and initialize CPU registers.
 */
static void __init
smp_cpu_init(int cpunum)
{
	extern int init_per_cpu(int);  /* arch/parisc/kernel/processor.c */
	extern void init_IRQ(void);    /* arch/parisc/kernel/irq.c */
	extern void start_cpu_itimer(void); /* arch/parisc/kernel/time.c */

	/* Set modes and Enable floating point coprocessor */
	(void) init_per_cpu(cpunum);

	disable_sr_hashing();

	mb();

	/* Well, support 2.4 linux scheme as well. */
	if (cpu_online(cpunum))	{
		extern void machine_halt(void); /* arch/parisc.../process.c */

		printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum);
		machine_halt();
	}

	notify_cpu_starting(cpunum);

	set_cpu_online(cpunum, true);

	/* Initialise the idle task for this CPU */
	atomic_inc(&init_mm.mm_count);
	current->active_mm = &init_mm;
	BUG_ON(current->mm);
	enter_lazy_tlb(&init_mm, current);

	init_IRQ();   /* make sure no IRQs are enabled or pending */
	start_cpu_itimer();
}
コード例 #8
0
ファイル: smp.c プロジェクト: 0-T-0/ps4-linux
asmlinkage void start_secondary(void)
{
	unsigned int cpu = smp_processor_id();
	struct mm_struct *mm = &init_mm;

	enable_mmu();
	atomic_inc(&mm->mm_count);
	atomic_inc(&mm->mm_users);
	current->active_mm = mm;
	enter_lazy_tlb(mm, current);
	local_flush_tlb_all();

	per_cpu_trap_init();

	preempt_disable();

	notify_cpu_starting(cpu);

	local_irq_enable();

	/* Enable local timers */
	local_timer_setup(cpu);
	calibrate_delay();

	smp_store_cpu_info(cpu);

	set_cpu_online(cpu, true);
	per_cpu(cpu_state, cpu) = CPU_ONLINE;

	cpu_startup_entry(CPUHP_ONLINE);
}
コード例 #9
0
ファイル: smp_pv.c プロジェクト: EMCAntimatter/linux
static void cpu_bringup(void)
{
	int cpu;

	cpu_init();
	touch_softlockup_watchdog();
	preempt_disable();

	/* PVH runs in ring 0 and allows us to do native syscalls. Yay! */
	if (!xen_feature(XENFEAT_supervisor_mode_kernel)) {
		xen_enable_sysenter();
		xen_enable_syscall();
	}
	cpu = smp_processor_id();
	smp_store_cpu_info(cpu);
	cpu_data(cpu).x86_max_cores = 1;
	set_cpu_sibling_map(cpu);

	speculative_store_bypass_ht_init();

	xen_setup_cpu_clockevents();

	notify_cpu_starting(cpu);

	set_cpu_online(cpu, true);

	cpu_set_state_online(cpu);  /* Implies full memory barrier. */

	/* We can take interrupts now: we're officially "up". */
	local_irq_enable();
}
コード例 #10
0
static void __cpuinit cpu_bringup(void)
{
	int cpu;

	cpu_init();
	touch_softlockup_watchdog();
	preempt_disable();

	xen_enable_sysenter();
	xen_enable_syscall();

	cpu = smp_processor_id();
	smp_store_cpu_info(cpu);
	cpu_data(cpu).x86_max_cores = 1;
	set_cpu_sibling_map(cpu);

	xen_setup_cpu_clockevents();

	notify_cpu_starting(cpu);

	ipi_call_lock();
	set_cpu_online(cpu, true);
	ipi_call_unlock();

	this_cpu_write(cpu_state, CPU_ONLINE);

	wmb();

	
	local_irq_enable();

	wmb();			
}
コード例 #11
0
/*
 *	Activate a secondary processor.
 */
int __cpuinit start_secondary(void *cpuvoid)
{
	/* Setup the cpu */
	cpu_init();
	preempt_disable();
	/* Enable TOD clock interrupts on the secondary cpu. */
	init_cpu_timer();
	/* Enable cpu timer interrupts on the secondary cpu. */
	init_cpu_vtimer();
	/* Enable pfault pseudo page faults on this cpu. */
	pfault_init();

	/* call cpu notifiers */
	notify_cpu_starting(smp_processor_id());
	/* Mark this cpu as online */
	ipi_call_lock();
	set_cpu_online(smp_processor_id(), true);
	ipi_call_unlock();
	__ctl_clear_bit(0, 28); /* Disable lowcore protection */
	S390_lowcore.restart_psw.mask =
		PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA;
	S390_lowcore.restart_psw.addr =
		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
	__ctl_set_bit(0, 28); /* Enable lowcore protection */
	local_irq_enable();
	/* cpu_idle will call schedule for us */
	cpu_idle();
	return 0;
}
コード例 #12
0
ファイル: smp.c プロジェクト: lbule/android_kernel_htc_m9pw
asmlinkage void __cpuinit secondary_start_kernel(void)
{
	struct mm_struct *mm = &init_mm;
	unsigned int cpu = smp_processor_id();

	printk("CPU%u: Booted secondary processor\n", cpu);

	atomic_inc(&mm->mm_count);
	current->active_mm = mm;
	cpumask_set_cpu(cpu, mm_cpumask(mm));

	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));

	cpu_set_reserved_ttbr0();
	flush_tlb_all();

	preempt_disable();
	trace_hardirqs_off();

	if (cpu_ops[cpu]->cpu_postboot)
		cpu_ops[cpu]->cpu_postboot();

	set_cpu_online(cpu, true);
	complete(&cpu_running);

	smp_store_cpu_info(cpu);

	notify_cpu_starting(cpu);

	local_dbg_enable();
	local_irq_enable();
	local_fiq_enable();

	cpu_startup_entry(CPUHP_ONLINE);
}
コード例 #13
0
ファイル: smp.c プロジェクト: 71eh/open80211s
/*
 *	Activate a secondary processor.
 */
int __cpuinit start_secondary(void *cpuvoid)
{
	cpu_init();
	preempt_disable();
	init_cpu_timer();
	init_cpu_vtimer();
	pfault_init();

	notify_cpu_starting(smp_processor_id());
	ipi_call_lock();
	set_cpu_online(smp_processor_id(), true);
	ipi_call_unlock();
	__ctl_clear_bit(0, 28); /* Disable lowcore protection */
	S390_lowcore.restart_psw.mask =
		PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA;
	S390_lowcore.restart_psw.addr =
		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
	__ctl_set_bit(0, 28); /* Enable lowcore protection */
	/*
	 * Wait until the cpu which brought this one up marked it
	 * active before enabling interrupts.
	 */
	while (!cpumask_test_cpu(smp_processor_id(), cpu_active_mask))
		cpu_relax();
	local_irq_enable();
	/* cpu_idle will call schedule for us */
	cpu_idle();
	return 0;
}
コード例 #14
0
ファイル: smp.c プロジェクト: bsingharora/linux
asmlinkage void start_secondary(void)
{
	unsigned int cpu = smp_processor_id();
	struct mm_struct *mm = &init_mm;

	enable_mmu();
	mmgrab(mm);
	mmget(mm);
	current->active_mm = mm;
#ifdef CONFIG_MMU
	enter_lazy_tlb(mm, current);
	local_flush_tlb_all();
#endif

	per_cpu_trap_init();

	preempt_disable();

	notify_cpu_starting(cpu);

	local_irq_enable();

	calibrate_delay();

	smp_store_cpu_info(cpu);

	set_cpu_online(cpu, true);
	per_cpu(cpu_state, cpu) = CPU_ONLINE;

	cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
コード例 #15
0
ファイル: smp.c プロジェクト: googyanas/GoogyMax-N5
/*
 * This is the secondary CPU boot entry.  We're using this CPUs
 * idle thread stack, but a set of temporary page tables.
 */
asmlinkage void __cpuinit secondary_start_kernel(void)
{
	struct mm_struct *mm = &init_mm;
	unsigned int cpu = smp_processor_id();

	/*
	 * All kernel threads share the same mm context; grab a
	 * reference and switch to it.
	 */
	atomic_inc(&mm->mm_count);
	current->active_mm = mm;
	cpumask_set_cpu(cpu, mm_cpumask(mm));

	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
	printk("CPU%u: Booted secondary processor\n", cpu);

	/*
	 * TTBR0 is only used for the identity mapping at this stage. Make it
	 * point to zero page to avoid speculatively fetching new entries.
	 */
	cpu_set_reserved_ttbr0();
	flush_tlb_all();

	preempt_disable();
	trace_hardirqs_off();

	if (cpu_ops[cpu]->cpu_postboot)
		cpu_ops[cpu]->cpu_postboot();

	/*
	 * Enable GIC and timers.
	 */

	smp_store_cpu_info(cpu);

	notify_cpu_starting(cpu);

	/*
	 * OK, now it's safe to let the boot CPU continue.  Wait for
	 * the CPU migration code to notice that the CPU is online
	 * before we continue.
	 */
	set_cpu_online(cpu, true);
	complete(&cpu_running);

	local_dbg_enable();
	/*
	 * Setup the percpu timer for this CPU.
	 */
	percpu_timer_setup();

	local_irq_enable();
	local_async_enable();

	/*
	 * OK, it's off to the idle thread for us
	 */
	cpu_startup_entry(CPUHP_ONLINE);
}
コード例 #16
0
ファイル: smp.c プロジェクト: cake654326/xpenology
/*
 * This is the secondary CPU boot entry.  We're using this CPUs
 * idle thread stack, but a set of temporary page tables.
 */
asmlinkage void __cpuinit secondary_start_kernel(void)
{
	struct mm_struct *mm = &init_mm;
	unsigned int cpu = smp_processor_id();

	printk("CPU%u: Booted secondary processor\n", cpu);

	/*
	 * All kernel threads share the same mm context; grab a
	 * reference and switch to it.
	 */
	atomic_inc(&mm->mm_count);
	current->active_mm = mm;
	cpumask_set_cpu(cpu, mm_cpumask(mm));

	/*
	 * TTBR0 is only used for the identity mapping at this stage. Make it
	 * point to zero page to avoid speculatively fetching new entries.
	 */
	cpu_set_reserved_ttbr0();
	flush_tlb_all();

	preempt_disable();
	trace_hardirqs_off();

	/*
	 * Let the primary processor know we're out of the
	 * pen, then head off into the C entry point
	 */
	write_pen_release(INVALID_HWID);

	/*
	 * Synchronise with the boot thread.
	 */
	raw_spin_lock(&boot_lock);
	raw_spin_unlock(&boot_lock);

	/*
	 * OK, now it's safe to let the boot CPU continue.  Wait for
	 * the CPU migration code to notice that the CPU is online
	 * before we continue.
	 */
	set_cpu_online(cpu, true);
	complete(&cpu_running);

	/*
	 * Enable GIC and timers.
	 */
	notify_cpu_starting(cpu);

	local_irq_enable();
	local_fiq_enable();

	/*
	 * OK, it's off to the idle thread for us
	 */
	cpu_startup_entry(CPUHP_ONLINE);
}
コード例 #17
0
/*
 * Report back to the Boot Processor during boot time or to the caller processor
 * during CPU online.
 */
static void smp_callin(void)
{
	int cpuid, phys_id;

	/*
	 * If waken up by an INIT in an 82489DX configuration
	 * cpu_callout_mask guarantees we don't get here before
	 * an INIT_deassert IPI reaches our local APIC, so it is
	 * now safe to touch our local APIC.
	 */
	cpuid = smp_processor_id();

	/*
	 * (This works even if the APIC is not enabled.)
	 */
	phys_id = read_apic_id();

	/*
	 * the boot CPU has finished the init stage and is spinning
	 * on callin_map until we finish. We are free to set up this
	 * CPU, first the APIC. (this is probably redundant on most
	 * boards)
	 */
	apic_ap_setup();

	/*
	 * Save our processor parameters. Note: this information
	 * is needed for clock calibration.
	 */
	smp_store_cpu_info(cpuid);

	/*
	 * Get our bogomips.
	 * Update loops_per_jiffy in cpu_data. Previous call to
	 * smp_store_cpu_info() stored a value that is close but not as
	 * accurate as the value just calculated.
	 */
	calibrate_delay();
	cpu_data(cpuid).loops_per_jiffy = loops_per_jiffy;
	pr_debug("Stack at about %p\n", &cpuid);

	/*
	 * This must be done before setting cpu_online_mask
	 * or calling notify_cpu_starting.
	 */
	set_cpu_sibling_map(raw_smp_processor_id());
	wmb();

	notify_cpu_starting(cpuid);

	/*
	 * Allow the master to continue.
	 */
	cpumask_set_cpu(cpuid, cpu_callin_mask);
}
コード例 #18
0
ファイル: smpboot.c プロジェクト: avsm/xen-1
/* 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(&current_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();
}
コード例 #19
0
ファイル: smp.c プロジェクト: AlexShiLucky/linux
void secondary_start_kernel(void)
{
	struct mm_struct *mm = &init_mm;
	unsigned int cpu = smp_processor_id();

	init_mmu();

#ifdef CONFIG_DEBUG_KERNEL
	if (boot_secondary_processors == 0) {
		pr_debug("%s: boot_secondary_processors:%d; Hanging cpu:%d\n",
			__func__, boot_secondary_processors, cpu);
		for (;;)
			__asm__ __volatile__ ("waiti " __stringify(LOCKLEVEL));
	}

	pr_debug("%s: boot_secondary_processors:%d; Booting cpu:%d\n",
		__func__, boot_secondary_processors, cpu);
#endif
	/* Init EXCSAVE1 */

	secondary_trap_init();

	/* All kernel threads share the same mm context. */

	mmget(mm);
	mmgrab(mm);
	current->active_mm = mm;
	cpumask_set_cpu(cpu, mm_cpumask(mm));
	enter_lazy_tlb(mm, current);

	preempt_disable();
	trace_hardirqs_off();

	calibrate_delay();

	notify_cpu_starting(cpu);

	secondary_init_irq();
	local_timer_setup(cpu);

	set_cpu_online(cpu, true);

	local_irq_enable();

	complete(&cpu_running);

	cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
コード例 #20
0
ファイル: smpboot.c プロジェクト: ChaOSChriS/bricked-flo
static void __init smp_online(void)
{
	int cpu_id = smp_processor_id();

	notify_cpu_starting(cpu_id);

	local_irq_enable();

	/* Get our bogomips. */
	calibrate_delay();

	/* Save our processor parameters */
 	smp_store_cpu_info(cpu_id);

	set_cpu_online(cpu_id, true);
}
コード例 #21
0
ファイル: smpboot.c プロジェクト: andyhhp/xen
/* Boot the current CPU */
void 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);

    identify_cpu(&current_cpu_data);

    init_traps();

    mmu_init_secondary_cpu();

    gic_init_secondary_cpu();

    init_secondary_IRQ();

    init_maintenance_interrupt();
    init_timer_interrupt();

    set_current(idle_vcpu[cpuid]);

    setup_cpu_sibling_map(cpuid);

    /* Run local notifiers */
    notify_cpu_starting(cpuid);
    /*
     * Ensure that previous writes are visible before marking the cpu as
     * online.
     */
    smp_wmb();

    /* Now report this CPU is up */
    cpumask_set_cpu(cpuid, &cpu_online_map);

    local_irq_enable();
    local_abort_enable();

    check_local_cpu_errata();

    printk(XENLOG_DEBUG "CPU %u booted.\n", smp_processor_id());

    startup_cpu_idle_loop();
}
コード例 #22
0
ファイル: smpboot.c プロジェクト: abligh/xen
/* 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();
}
コード例 #23
0
static int idle_proc(void *cpup)
{
	int cpu = (int) cpup, err;

	err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
	if (err < 0)
		panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);

	os_set_fd_async(cpu_data[cpu].ipi_pipe[0]);

	wmb();
	if (cpu_test_and_set(cpu, cpu_callin_map)) {
		printk(KERN_ERR "huh, CPU#%d already present??\n", cpu);
		BUG();
	}

	while (!cpu_isset(cpu, smp_commenced_mask))
		cpu_relax();

	notify_cpu_starting(cpu);
<<<<<<< HEAD
コード例 #24
0
static void __cpuinit
smp_callin (void)
{
	int cpuid, phys_id, itc_master;
	struct cpuinfo_ia64 *last_cpuinfo, *this_cpuinfo;
	extern void ia64_init_itm(void);
	extern volatile int time_keeper_id;

#ifdef CONFIG_PERFMON
	extern void pfm_init_percpu(void);
#endif

	cpuid = smp_processor_id();
	phys_id = hard_smp_processor_id();
	itc_master = time_keeper_id;

	if (cpu_online(cpuid)) {
		printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
		       phys_id, cpuid);
		BUG();
	}

	fix_b0_for_bsp();

	/*
	 * numa_node_id() works after this.
	 */
	set_numa_node(cpu_to_node_map[cpuid]);
	set_numa_mem(local_memory_node(cpu_to_node_map[cpuid]));

	ipi_call_lock_irq();
	spin_lock(&vector_lock);
	/* Setup the per cpu irq handling data structures */
	__setup_vector_irq(cpuid);
	notify_cpu_starting(cpuid);
	set_cpu_online(cpuid, true);
	per_cpu(cpu_state, cpuid) = CPU_ONLINE;
	spin_unlock(&vector_lock);
	ipi_call_unlock_irq();

	smp_setup_percpu_timer();

	ia64_mca_cmc_vector_setup();	/* Setup vector on AP */

#ifdef CONFIG_PERFMON
	pfm_init_percpu();
#endif

	local_irq_enable();

	if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
		/*
		 * Synchronize the ITC with the BP.  Need to do this after irqs are
		 * enabled because ia64_sync_itc() calls smp_call_function_single(), which
		 * calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls
		 * local_bh_enable(), which bugs out if irqs are not enabled...
		 */
		Dprintk("Going to syncup ITC with ITC Master.\n");
		ia64_sync_itc(itc_master);
	}

	/*
	 * Get our bogomips.
	 */
	ia64_init_itm();

	/*
	 * Delay calibration can be skipped if new processor is identical to the
	 * previous processor.
	 */
	last_cpuinfo = cpu_data(cpuid - 1);
	this_cpuinfo = local_cpu_data;
	if (last_cpuinfo->itc_freq != this_cpuinfo->itc_freq ||
	    last_cpuinfo->proc_freq != this_cpuinfo->proc_freq ||
	    last_cpuinfo->features != this_cpuinfo->features ||
	    last_cpuinfo->revision != this_cpuinfo->revision ||
	    last_cpuinfo->family != this_cpuinfo->family ||
	    last_cpuinfo->archrev != this_cpuinfo->archrev ||
	    last_cpuinfo->model != this_cpuinfo->model)
		calibrate_delay();
	local_cpu_data->loops_per_jiffy = loops_per_jiffy;

	/*
	 * Allow the master to continue.
	 */
	cpu_set(cpuid, cpu_callin_map);
	Dprintk("Stack on CPU %d at about %p\n",cpuid, &cpuid);
}
コード例 #25
0
/* Activate a secondary processor. */
int __devinit start_secondary(void *unused)
{
	unsigned int cpu = smp_processor_id();
	struct device_node *l2_cache;
	int i, base;

	atomic_inc(&init_mm.mm_count);
	current->active_mm = &init_mm;

	smp_store_cpu_info(cpu);

#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
	/* Clear any pending timer interrupts */
	mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);

	/* Enable decrementer interrupt */
	mtspr(SPRN_TCR, TCR_DIE);
#endif
	set_dec(tb_ticks_per_jiffy);
	preempt_disable();
	cpu_callin_map[cpu] = 1;

	if (smp_ops->setup_cpu)
		smp_ops->setup_cpu(cpu);
	if (smp_ops->take_timebase)
		smp_ops->take_timebase();

	if (system_state > SYSTEM_BOOTING)
		snapshot_timebase();

	secondary_cpu_time_init();

	ipi_call_lock();
	notify_cpu_starting(cpu);
	set_cpu_online(cpu, true);
	/* Update sibling maps */
	base = cpu_first_thread_in_core(cpu);
	for (i = 0; i < threads_per_core; i++) {
		if (cpu_is_offline(base + i))
			continue;
		cpumask_set_cpu(cpu, cpu_sibling_mask(base + i));
		cpumask_set_cpu(base + i, cpu_sibling_mask(cpu));

		/* cpu_core_map should be a superset of
		 * cpu_sibling_map even if we don't have cache
		 * information, so update the former here, too.
		 */
		cpumask_set_cpu(cpu, cpu_core_mask(base + i));
		cpumask_set_cpu(base + i, cpu_core_mask(cpu));
	}
	l2_cache = cpu_to_l2cache(cpu);
	for_each_online_cpu(i) {
		struct device_node *np = cpu_to_l2cache(i);
		if (!np)
			continue;
		if (np == l2_cache) {
			cpumask_set_cpu(cpu, cpu_core_mask(i));
			cpumask_set_cpu(i, cpu_core_mask(cpu));
		}
		of_node_put(np);
	}
	of_node_put(l2_cache);
	ipi_call_unlock();

	local_irq_enable();

	cpu_idle();
	return 0;
}
コード例 #26
0
static void __devinit
smp_callin (void)
{
#ifdef XEN
	/* work around for spinlock irq assert. */
	unsigned long flags;
#endif
	int cpuid, phys_id;
	extern void ia64_init_itm(void);

#ifdef CONFIG_PERFMON
	extern void pfm_init_percpu(void);
#endif

	cpuid = smp_processor_id();
	phys_id = hard_smp_processor_id();

	if (cpu_online(cpuid)) {
		printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
		       phys_id, cpuid);
		BUG();
	}

	fix_b0_for_bsp();

#ifdef XEN
	notify_cpu_starting(cpuid);
	lock_ipi_calllock(&flags);
#else
	lock_ipi_calllock();
#endif
	cpu_set(cpuid, cpu_online_map);
#ifdef XEN
	unlock_ipi_calllock(flags);
#else
	unlock_ipi_calllock();
#endif
	per_cpu(cpu_state, cpuid) = CPU_ONLINE;

	smp_setup_percpu_timer();

	ia64_mca_cmc_vector_setup();	/* Setup vector on AP */

#ifdef CONFIG_PERFMON
	pfm_init_percpu();
#endif

	local_irq_enable();

	if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
		/*
		 * Synchronize the ITC with the BP.  Need to do this after irqs are
		 * enabled because ia64_sync_itc() calls smp_call_function_single(), which
		 * calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls
		 * local_bh_enable(), which bugs out if irqs are not enabled...
		 */
		Dprintk("Going to syncup ITC with BP.\n");
		ia64_sync_itc(0);
	}

	/*
	 * Get our bogomips.
	 */
	ia64_init_itm();
#ifndef XEN
	calibrate_delay();
#endif
	local_cpu_data->loops_per_jiffy = loops_per_jiffy;

#ifdef CONFIG_IA32_SUPPORT
	ia32_gdt_init();
#endif

	/*
	 * Allow the master to continue.
	 */
	cpu_set(cpuid, cpu_callin_map);
	Dprintk("Stack on CPU %d at about %p\n",cpuid, &cpuid);
}
コード例 #27
0
ファイル: smp.c プロジェクト: myjang0507/eas-backports
/* Activate a secondary processor. */
__cpuinit void start_secondary(void *unused)
{
	unsigned int cpu = smp_processor_id();
	struct device_node *l2_cache;
	int i, base;

	atomic_inc(&init_mm.mm_count);
	current->active_mm = &init_mm;

	smp_store_cpu_info(cpu);
	set_dec(tb_ticks_per_jiffy);
	preempt_disable();
	cpu_callin_map[cpu] = 1;

	if (smp_ops->setup_cpu)
		smp_ops->setup_cpu(cpu);
	if (smp_ops->take_timebase)
		smp_ops->take_timebase();

	secondary_cpu_time_init();

#ifdef CONFIG_PPC64
	if (system_state == SYSTEM_RUNNING)
		vdso_data->processorCount++;

	vdso_getcpu_init();
#endif
	notify_cpu_starting(cpu);
	set_cpu_online(cpu, true);
	/* Update sibling maps */
	base = cpu_first_thread_sibling(cpu);
	for (i = 0; i < threads_per_core; i++) {
		if (cpu_is_offline(base + i))
			continue;
		cpumask_set_cpu(cpu, cpu_sibling_mask(base + i));
		cpumask_set_cpu(base + i, cpu_sibling_mask(cpu));

		/* cpu_core_map should be a superset of
		 * cpu_sibling_map even if we don't have cache
		 * information, so update the former here, too.
		 */
		cpumask_set_cpu(cpu, cpu_core_mask(base + i));
		cpumask_set_cpu(base + i, cpu_core_mask(cpu));
	}
	l2_cache = cpu_to_l2cache(cpu);
	for_each_online_cpu(i) {
		struct device_node *np = cpu_to_l2cache(i);
		if (!np)
			continue;
		if (np == l2_cache) {
			cpumask_set_cpu(cpu, cpu_core_mask(i));
			cpumask_set_cpu(i, cpu_core_mask(cpu));
		}
		of_node_put(np);
	}
	of_node_put(l2_cache);

	local_irq_enable();

	cpu_startup_entry(CPUHP_ONLINE);

	BUG();
}
コード例 #28
0
ファイル: smpboot.c プロジェクト: bitfurry/linux
/*
 * Report back to the Boot Processor during boot time or to the caller processor
 * during CPU online.
 */
static void smp_callin(void)
{
	int cpuid, phys_id;

	/*
	 * If waken up by an INIT in an 82489DX configuration
	 * we may get here before an INIT-deassert IPI reaches
	 * our local APIC.  We have to wait for the IPI or we'll
	 * lock up on an APIC access.
	 *
	 * Since CPU0 is not wakened up by INIT, it doesn't wait for the IPI.
	 */
	cpuid = smp_processor_id();
	if (apic->wait_for_init_deassert && cpuid)
		while (!atomic_read(&init_deasserted))
			cpu_relax();

	/*
	 * (This works even if the APIC is not enabled.)
	 */
	phys_id = read_apic_id();

	/*
	 * the boot CPU has finished the init stage and is spinning
	 * on callin_map until we finish. We are free to set up this
	 * CPU, first the APIC. (this is probably redundant on most
	 * boards)
	 */

	pr_debug("CALLIN, before setup_local_APIC()\n");
	if (apic->smp_callin_clear_local_apic)
		apic->smp_callin_clear_local_apic();
	setup_local_APIC();
	end_local_APIC_setup();

	/*
	 * Need to setup vector mappings before we enable interrupts.
	 */
	setup_vector_irq(smp_processor_id());

	/*
	 * Save our processor parameters. Note: this information
	 * is needed for clock calibration.
	 */
	smp_store_cpu_info(cpuid);

	/*
	 * Get our bogomips.
	 * Update loops_per_jiffy in cpu_data. Previous call to
	 * smp_store_cpu_info() stored a value that is close but not as
	 * accurate as the value just calculated.
	 */
	calibrate_delay();
	cpu_data(cpuid).loops_per_jiffy = loops_per_jiffy;
	pr_debug("Stack at about %p\n", &cpuid);

	/*
	 * This must be done before setting cpu_online_mask
	 * or calling notify_cpu_starting.
	 */
	set_cpu_sibling_map(raw_smp_processor_id());
	wmb();

	notify_cpu_starting(cpuid);

	/*
	 * Allow the master to continue.
	 */
	cpumask_set_cpu(cpuid, cpu_callin_mask);
}
コード例 #29
0
/*
 * Report back to the Boot Processor during boot time or to the caller processor
 * during CPU online.
 */
static void __cpuinit smp_callin(void)
{
    int cpuid, phys_id;
    unsigned long timeout;

    /*
     * If waken up by an INIT in an 82489DX configuration
     * we may get here before an INIT-deassert IPI reaches
     * our local APIC.  We have to wait for the IPI or we'll
     * lock up on an APIC access.
     *
     * Since CPU0 is not wakened up by INIT, it doesn't wait for the IPI.
     */
    cpuid = smp_processor_id();
    if (apic->wait_for_init_deassert && cpuid != 0)
        apic->wait_for_init_deassert(&init_deasserted);

    /*
     * (This works even if the APIC is not enabled.)
     */
    phys_id = read_apic_id();
    if (cpumask_test_cpu(cpuid, cpu_callin_mask)) {
        panic("%s: phys CPU#%d, CPU#%d already present??\n", __func__,
              phys_id, cpuid);
    }
    pr_debug("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpuid, phys_id);

    /*
     * STARTUP IPIs are fragile beasts as they might sometimes
     * trigger some glue motherboard logic. Complete APIC bus
     * silence for 1 second, this overestimates the time the
     * boot CPU is spending to send the up to 2 STARTUP IPIs
     * by a factor of two. This should be enough.
     */

    /*
     * Waiting 2s total for startup (udelay is not yet working)
     */
    timeout = jiffies + 2*HZ;
    while (time_before(jiffies, timeout)) {
        /*
         * Has the boot CPU finished it's STARTUP sequence?
         */
        if (cpumask_test_cpu(cpuid, cpu_callout_mask))
            break;
        cpu_relax();
    }

    if (!time_before(jiffies, timeout)) {
        panic("%s: CPU%d started up but did not get a callout!\n",
              __func__, cpuid);
    }

    /*
     * the boot CPU has finished the init stage and is spinning
     * on callin_map until we finish. We are free to set up this
     * CPU, first the APIC. (this is probably redundant on most
     * boards)
     */

    pr_debug("CALLIN, before setup_local_APIC()\n");
    if (apic->smp_callin_clear_local_apic)
        apic->smp_callin_clear_local_apic();
    setup_local_APIC();
    end_local_APIC_setup();

    /*
     * Need to setup vector mappings before we enable interrupts.
     */
    setup_vector_irq(smp_processor_id());

    /*
     * Save our processor parameters. Note: this information
     * is needed for clock calibration.
     */
    smp_store_cpu_info(cpuid);

    /*
     * Get our bogomips.
     * Update loops_per_jiffy in cpu_data. Previous call to
     * smp_store_cpu_info() stored a value that is close but not as
     * accurate as the value just calculated.
     */
    calibrate_delay();
    cpu_data(cpuid).loops_per_jiffy = loops_per_jiffy;
    pr_debug("Stack at about %p\n", &cpuid);

    /*
     * This must be done before setting cpu_online_mask
     * or calling notify_cpu_starting.
     */
    set_cpu_sibling_map(raw_smp_processor_id());
    wmb();

    notify_cpu_starting(cpuid);

    /*
     * Allow the master to continue.
     */
    cpumask_set_cpu(cpuid, cpu_callin_mask);
}
コード例 #30
0
ファイル: smp.c プロジェクト: bradbishop/linux
/*
 * This is the secondary CPU boot entry.  We're using this CPUs
 * idle thread stack, but a set of temporary page tables.
 */
asmlinkage void secondary_start_kernel(void)
{
	struct mm_struct *mm = &init_mm;
	unsigned int cpu = smp_processor_id();

	/*
	 * All kernel threads share the same mm context; grab a
	 * reference and switch to it.
	 */
	atomic_inc(&mm->mm_count);
	current->active_mm = mm;

	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));

	/*
	 * TTBR0 is only used for the identity mapping at this stage. Make it
	 * point to zero page to avoid speculatively fetching new entries.
	 */
	cpu_uninstall_idmap();

	preempt_disable();
	trace_hardirqs_off();

	/*
	 * If the system has established the capabilities, make sure
	 * this CPU ticks all of those. If it doesn't, the CPU will
	 * fail to come online.
	 */
	verify_local_cpu_capabilities();

	if (cpu_ops[cpu]->cpu_postboot)
		cpu_ops[cpu]->cpu_postboot();

	/*
	 * Log the CPU info before it is marked online and might get read.
	 */
	cpuinfo_store_cpu();

	/*
	 * Enable GIC and timers.
	 */
	notify_cpu_starting(cpu);

	store_cpu_topology(cpu);

	/*
	 * OK, now it's safe to let the boot CPU continue.  Wait for
	 * the CPU migration code to notice that the CPU is online
	 * before we continue.
	 */
	pr_info("CPU%u: Booted secondary processor [%08x]\n",
					 cpu, read_cpuid_id());
	update_cpu_boot_status(CPU_BOOT_SUCCESS);
	set_cpu_online(cpu, true);
	complete(&cpu_running);

	local_irq_enable();
	local_async_enable();

	/*
	 * OK, it's off to the idle thread for us
	 */
	cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}