Exemplo n.º 1
2
void __init setup_boot_APIC_clock(void)
{
	unsigned long flags;
	apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n");
	using_apic_timer = 1;

	local_irq_save(flags);

	calibration_result = calibrate_APIC_clock();
	/*
	 * Now set up the timer for real.
	 */
	setup_APIC_timer(calibration_result);

	local_irq_restore(flags);
}
Exemplo n.º 2
1
void __init setup_boot_APIC_clock(void)
{

    if (disable_apic_timer) {
        pr_info("Disabling APIC timer\n");

        if (num_possible_cpus() > 1) {
            lapic_clockevent.mult = 1;
            setup_APIC_timer();
        }
        return;
    }

    apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
                "calibrating APIC timer ...\n");

    if (calibrate_APIC_clock()) {

        if (num_possible_cpus() > 1)
            setup_APIC_timer();
        return;
    }


    if (nmi_watchdog != NMI_IO_APIC)
        lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
    else
        pr_warning("APIC timer registered as dummy,"
                   " due to nmi_watchdog=%d!\n", nmi_watchdog);


    setup_APIC_timer();
}
Exemplo n.º 3
0
void __init setup_boot_APIC_clock (void)
{
	/*
	 * The local apic timer can be disabled via the kernel commandline.
	 * Register the lapic timer as a dummy clock event source on SMP
	 * systems, so the broadcast mechanism is used. On UP systems simply
	 * ignore it.
	 */
	if (disable_apic_timer) {
		printk(KERN_INFO "Disabling APIC timer\n");
		/* No broadcast on UP ! */
		if (num_possible_cpus() > 1)
			setup_APIC_timer();
		return;
	}

	printk(KERN_INFO "Using local APIC timer interrupts.\n");
	calibrate_APIC_clock();

	/*
	 * If nmi_watchdog is set to IO_APIC, we need the
	 * PIT/HPET going.  Otherwise register lapic as a dummy
	 * device.
	 */
	if (nmi_watchdog != NMI_IO_APIC)
		lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
	else
		printk(KERN_WARNING "APIC timer registered as dummy,"
		       " due to nmi_watchdog=1!\n");

	setup_APIC_timer();
}
Exemplo n.º 4
0
void __init setup_boot_APIC_clock(void)
{
	apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n");
	using_apic_timer = 1;

	local_irq_disable();

	calibration_result = calibrate_APIC_clock();
	/*
	 * Now set up the timer for real.
	 */
	setup_APIC_timer(calibration_result);

	local_irq_enable();
}
Exemplo n.º 5
0
void __init setup_APIC_clocks (void)
{
	printk("Using local APIC timer interrupts.\n");
	using_apic_timer = 1;

	__cli();

	calibration_result = calibrate_APIC_clock();
	/*
	 * Now set up the timer for real.
	 */
	setup_APIC_timer((void *)calibration_result);

	__sti();

	/* and update all other cpus */
	smp_call_function(setup_APIC_timer, (void *)calibration_result, 1, 1);
}
Exemplo n.º 6
0
void __init setup_boot_APIC_clock(void)
{
    unsigned long flags;
    apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n");
    using_apic_timer = 1;

    local_irq_save(flags);

    calibrate_APIC_clock();

    if ( tdt_enable && boot_cpu_has(X86_FEATURE_TSC_DEADLINE) )
    {
        printk(KERN_DEBUG "TSC deadline timer enabled\n");
        tdt_enabled = 1;
    }

    setup_APIC_timer();
    
    local_irq_restore(flags);
}
Exemplo n.º 7
0
void __init setup_boot_APIC_clock (void)
{
	if (disable_apic_timer) { 
		printk(KERN_INFO "Disabling APIC timer\n"); 
		return; 
	} 

	printk(KERN_INFO "Using local APIC timer interrupts.\n");
	using_apic_timer = 1;

	local_irq_disable();

	calibration_result = calibrate_APIC_clock();
	/*
	 * Now set up the timer for real.
	 */
	setup_APIC_timer(calibration_result);

	local_irq_enable();
}
Exemplo n.º 8
0
void __init setup_APIC_clocks (void)
{
	/* Disabled by DMI scan or kernel option? */
	if (dont_use_local_apic_timer)
		return;

	printk("Using local APIC timer interrupts.\n");
	using_apic_timer = 1;

	__cli();

	calibration_result = calibrate_APIC_clock();
	/*
	 * Now set up the timer for real.
	 */
	setup_APIC_timer((void *)(u64)calibration_result);

	__sti();

	/* and update all other cpus */
	smp_call_function(setup_APIC_timer, (void *)(u64)calibration_result, 1, 1);
}
Exemplo n.º 9
0
void __init setup_secondary_APIC_clock(void)
{
	local_irq_disable(); /* FIXME: Do we need this? --RR */
	setup_APIC_timer(calibration_result);
	local_irq_enable();
}
Exemplo n.º 10
0
void __init setup_secondary_APIC_clock(void)
{
	setup_APIC_timer(calibration_result);
}
Exemplo n.º 11
0
void __devinit setup_secondary_APIC_clock(void)
{
    setup_APIC_timer();
}
Exemplo n.º 12
0
void __cpuinit setup_secondary_APIC_clock(void)
{
	check_boot_apic_timer_broadcast();
	setup_APIC_timer();
}
Exemplo n.º 13
0
void __cpuinit setup_secondary_APIC_clock(void)
{
	local_irq_disable(); /* FIXME: Do we need this? --RR */
	setup_APIC_timer();
	local_irq_enable();
}
Exemplo n.º 14
0
/*
 * Setup the boot APIC
 *
 * Calibrate and verify the result.
 */
void __init setup_boot_APIC_clock(void)
{
	struct clock_event_device *levt = &__get_cpu_var(lapic_events);
	const long pm_100ms = PMTMR_TICKS_PER_SEC/10;
	const long pm_thresh = pm_100ms/100;
	void (*real_handler)(struct clock_event_device *dev);
	unsigned long deltaj;
	long delta, deltapm;
	int pm_referenced = 0;

	apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
		    "calibrating APIC timer ...\n");

	local_irq_disable();

	/* Replace the global interrupt handler */
	real_handler = global_clock_event->event_handler;
	global_clock_event->event_handler = lapic_cal_handler;

	/*
	 * Setup the APIC counter to 1e9. There is no way the lapic
	 * can underflow in the 100ms detection time frame
	 */
	__setup_APIC_LVTT(1000000000, 0, 0);

	/* Let the interrupts run */
	local_irq_enable();

	while (lapic_cal_loops <= LAPIC_CAL_LOOPS)
		cpu_relax();

	local_irq_disable();

	/* Restore the real event handler */
	global_clock_event->event_handler = real_handler;

	/* Build delta t1-t2 as apic timer counts down */
	delta = lapic_cal_t1 - lapic_cal_t2;
	apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta);

	/* Check, if the PM timer is available */
	deltapm = lapic_cal_pm2 - lapic_cal_pm1;
	apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm);

	if (deltapm) {
		unsigned long mult;
		u64 res;

		mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC, 22);

		if (deltapm > (pm_100ms - pm_thresh) &&
		    deltapm < (pm_100ms + pm_thresh)) {
			apic_printk(APIC_VERBOSE, "... PM timer result ok\n");
		} else {
			res = (((u64) deltapm) *  mult) >> 22;
			do_div(res, 1000000);
			printk(KERN_WARNING "APIC calibration not consistent "
			       "with PM Timer: %ldms instead of 100ms\n",
			       (long)res);
			/* Correct the lapic counter value */
			res = (((u64) delta ) * pm_100ms);
			do_div(res, deltapm);
			printk(KERN_INFO "APIC delta adjusted to PM-Timer: "
			       "%lu (%ld)\n", (unsigned long) res, delta);
			delta = (long) res;
		}
		pm_referenced = 1;
	}

	/* Calculate the scaled math multiplication factor */
	lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS, 32);
	lapic_clockevent.max_delta_ns =
		clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
	lapic_clockevent.min_delta_ns =
		clockevent_delta2ns(0xF, &lapic_clockevent);

	calibration_result = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;

	apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta);
	apic_printk(APIC_VERBOSE, "..... mult: %ld\n", lapic_clockevent.mult);
	apic_printk(APIC_VERBOSE, "..... calibration result: %u\n",
		    calibration_result);

	if (cpu_has_tsc) {
		delta = (long)(lapic_cal_tsc2 - lapic_cal_tsc1);
		apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
			    "%ld.%04ld MHz.\n",
			    (delta / LAPIC_CAL_LOOPS) / (1000000 / HZ),
			    (delta / LAPIC_CAL_LOOPS) % (1000000 / HZ));
	}

	apic_printk(APIC_VERBOSE, "..... host bus clock speed is "
		    "%u.%04u MHz.\n",
		    calibration_result / (1000000 / HZ),
		    calibration_result % (1000000 / HZ));

	local_apic_timer_verify_ok = 1;

	/* We trust the pm timer based calibration */
	if (!pm_referenced) {
		apic_printk(APIC_VERBOSE, "... verify APIC timer\n");

		/*
		 * Setup the apic timer manually
		 */
		levt->event_handler = lapic_cal_handler;
		lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt);
		lapic_cal_loops = -1;

		/* Let the interrupts run */
		local_irq_enable();

		while(lapic_cal_loops <= LAPIC_CAL_LOOPS)
			cpu_relax();

		local_irq_disable();

		/* Stop the lapic timer */
		lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt);

		local_irq_enable();

		/* Jiffies delta */
		deltaj = lapic_cal_j2 - lapic_cal_j1;
		apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj);

		/* Check, if the jiffies result is consistent */
		if (deltaj >= LAPIC_CAL_LOOPS-2 && deltaj <= LAPIC_CAL_LOOPS+2)
			apic_printk(APIC_VERBOSE, "... jiffies result ok\n");
		else
			local_apic_timer_verify_ok = 0;
	}

	if (!local_apic_timer_verify_ok) {
		printk(KERN_WARNING
		       "APIC timer disabled due to verification failure.\n");
		/* No broadcast on UP ! */
		if (num_possible_cpus() == 1)
			return;
	} else {
		/*
		 * If nmi_watchdog is set to IO_APIC, we need the
		 * PIT/HPET going.  Otherwise register lapic as a dummy
		 * device.
		 */
		if (nmi_watchdog != NMI_IO_APIC)
			lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
	}

	/* Setup the lapic or request the broadcast */
	setup_APIC_timer();
}