示例#1
0
static void smp_halt(void)
{
	int cpuid = safe_smp_processor_id(); 
	static int first_entry = 1;

	if (reboot_force)
		return;

	if (first_entry) {
		first_entry = 0;
		smp_call_function((void *)machine_restart, NULL, 1, 0);
	}
			
	smp_stop_cpu(); 

	/* AP calling this. Just halt */
	if (cpuid != boot_cpu_id) { 
		for (;;) 
			asm("hlt");
	}

	/* Wait for all other CPUs to have run smp_stop_cpu */
	while (!cpus_empty(cpu_online_map))
		rep_nop(); 
}
示例#2
0
/* TSC based delay: */
static void delay_tsc(unsigned long loops)
{
	unsigned long bclock, now;
	int cpu;

	preempt_disable();
	cpu = smp_processor_id();
	rdtscl(bclock);
	for (;;) {
		rdtscl(now);
		if ((now - bclock) >= loops)
			break;

		/* Allow RT tasks to run */
		preempt_enable();
		rep_nop();
		preempt_disable();

		/*
		 * It is possible that we moved to another CPU, and
		 * since TSC's are per-cpu we need to calculate
		 * that. The delay must guarantee that we wait "at
		 * least" the amount of time. Being moved to another
		 * CPU could make the wait longer but we just need to
		 * make sure we waited long enough. Rebalance the
		 * counter for this CPU.
		 */
		if (unlikely(cpu != smp_processor_id())) {
			loops -= (now - bclock);
			cpu = smp_processor_id();
			rdtscl(bclock);
		}
	}
	preempt_enable();
}
static void es7000_spin(int n)
{
    int i = 0;

    while (i++ < n)
        rep_nop();
}
示例#4
0
/*
 * Activate a secondary processor.
 */
static void __init start_secondary(void *unused)
{
	/*
	 * Dont put anything before smp_callin(), SMP
	 * booting is too fragile that we want to limit the
	 * things done here to the most necessary things.
	 */
	cpu_init();
	smp_callin();
	while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
		rep_nop();
	setup_secondary_APIC_clock();
	if (nmi_watchdog == NMI_IO_APIC) {
		disable_8259A_irq(0);
		enable_NMI_through_LVT0(NULL);
		enable_8259A_irq(0);
	}
	enable_APIC_timer();
	/*
	 * low-memory mappings have been cleared, flush them from
	 * the local TLBs too.
	 */
	local_flush_tlb();
	cpu_set(smp_processor_id(), cpu_online_map);

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

	wmb();
	cpu_idle();
}
示例#5
0
文件: delay.c 项目: wesen/lemonix
/* TSC based delay: */
static notrace void delay_tsc(unsigned long loops)
{
	unsigned long bclock, now;

	rdtscl(bclock);
	do {
		rep_nop();
		rdtscl(now);
	} while ((now-bclock) < loops);
}
示例#6
0
void __delay(unsigned long loops)
{
	unsigned bclock, now;
	
	rdtscl(bclock);
	do
	{
		rep_nop(); 
		rdtscl(now);
	}
	while((now-bclock) < loops);
}
示例#7
0
文件: delay.c 项目: cilynx/dd-wrt
/* TSC based delay: */
static void delay_tsc(unsigned long loops)
{
	unsigned long bclock, now;

	preempt_disable();		/* TSC's are per-cpu */
	rdtscl(bclock);
	do {
		rep_nop();
		rdtscl(now);
	} while ((now-bclock) < loops);
	preempt_enable();
}
示例#8
0
static void delay_hpet(unsigned long loops)
{
	unsigned long hpet_start, hpet_end;
	unsigned long eax;

	/* loops is the number of cpu cycles. Convert it to hpet clocks */
	ASM_MUL64_REG(eax, loops, tsc_hpet_quotient, loops);

	hpet_start = hpet_readl(HPET_COUNTER);
	do {
		rep_nop();
		hpet_end = hpet_readl(HPET_COUNTER);
	} while ((hpet_end - hpet_start) < (loops));
}
示例#9
0
void ndelay(const unsigned long nsec)
{

    struct timeval now, end;

    gettimeofday(&end, NULL);
    end.tv_usec += (nsec + 999) / 1000;
    while (end.tv_usec > 1000000) {
	end.tv_usec -= 1000000;
	end.tv_sec++;
    }

    do {
	rep_nop();
	gettimeofday(&now, NULL);
    } while (now.tv_sec == end.tv_sec ? now.tv_usec < end.tv_usec : now.tv_sec < end.tv_sec);
}
示例#10
0
/*
 * Activate a secondary processor.
 */
void __init start_secondary(void)
{
	/*
	 * Dont put anything before smp_callin(), SMP
	 * booting is too fragile that we want to limit the
	 * things done here to the most necessary things.
	 */
	cpu_init();
	smp_callin();

	/* otherwise gcc will move up the smp_processor_id before the cpu_init */
	barrier();

	Dprintk("cpu %d: waiting for commence\n", smp_processor_id()); 
	while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
		rep_nop();

	Dprintk("cpu %d: setting up apic clock\n", smp_processor_id()); 	
	setup_secondary_APIC_clock();

	Dprintk("cpu %d: enabling apic timer\n", smp_processor_id()); 

	if (nmi_watchdog == NMI_IO_APIC) {
		disable_8259A_irq(0);
		enable_NMI_through_LVT0(NULL);
		enable_8259A_irq(0);
	}


	enable_APIC_timer(); 

	/*
	 * low-memory mappings have been cleared, flush them from
	 * the local TLBs too.
	 */
	local_flush_tlb();

	Dprintk("cpu %d eSetting cpu_online_map\n", smp_processor_id()); 
	cpu_set(smp_processor_id(), cpu_online_map);
	wmb();
	
	cpu_idle();
}
示例#11
0
static void __init 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.
	 */
	wait_for_init_deassert(&init_deasserted);

	/*
	 * (This works even if the APIC is not enabled.)
	 */
	phys_id = GET_APIC_ID(apic_read(APIC_ID));
	cpuid = smp_processor_id();
	if (cpu_isset(cpuid, cpu_callin_map)) {
		printk("huh, phys CPU#%d, CPU#%d already present??\n",
					phys_id, cpuid);
		BUG();
	}
	Dprintk("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 (cpu_isset(cpuid, cpu_callout_map))
			break;
		rep_nop();
	}

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

	/*
	 * 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)
	 */

	Dprintk("CALLIN, before setup_local_APIC().\n");
	smp_callin_clear_local_apic();
	setup_local_APIC();
	map_cpu_to_logical_apicid();

	/*
	 * Get our bogomips.
	 */
	calibrate_delay();
	Dprintk("Stack at about %p\n",&cpuid);

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

	disable_APIC_timer();

	/*
	 * Allow the master to continue.
	 */
	cpu_set(cpuid, cpu_callin_map);

	/*
	 *      Synchronize the TSC with the BP
	 */
	if (cpu_has_tsc && cpu_khz)
		synchronize_tsc_ap();
}