Esempio n. 1
0
static void smp_delay(int time)
{				/*delays time * 10 msec */
	int i;
	for (i = 0; i < time; i++)
		wait_8254_wraparound();
	return;
}
Esempio n. 2
0
File: lapic.c Progetto: mczero80/jx
void calibrate_APIC_clock(void)
{

	long tt1, tt2;
	int i;

	const int LOOPS = HZ / 10;

	dprintf("calibrating APIC timer ...\n");

	setup_APIC_LVTT(0xffffffff);
	disable_APIC_clock(0 /*dummy */ );	/* disable timer IRQ */

	/* Let's wait for a wraparound to start exact measurement */
	wait_8254_wraparound();

	/* We wrapped around just now. Let's start */
	tt1 = apic_read(APIC_TMCCT);

	/* Let's wait LOOPS wraprounds */
	for (i = 0; i < LOOPS; i++)
		wait_8254_wraparound();

	tt2 = apic_read(APIC_TMCCT);

	calibration_result = ((tt1 - tt2)	/* clocks for LOOPS */
			      /LOOPS);	/* clocks per LOOP */

	/* init timer to std timeslice */
	set_APIC_clock(XXX);
#ifdef SMP
	wait_8254_wraparound();	//ttt
	smp_call_function(APIC_DEST_ALLBUT, setup_APIC_LVTT, (void *) (XXX * calibration_result), 1, NULL);
#endif
	dprintf("..... host bus clock speed is %ld.%04ld MHz.\n", (calibration_result * APIC_DIVISOR) / (1000000 / HZ),
		(calibration_result * APIC_DIVISOR) % (1000000 / HZ));
}
Esempio n. 3
0
void setup_APIC_timer(void * data)
{
	unsigned int clocks = (unsigned int) data, slice, t0, t1;
	unsigned long flags;
	int delta;

	__save_flags(flags);
	__sti();
	/*
	 * ok, Intel has some smart code in their APIC that knows
	 * if a CPU was in 'hlt' lowpower mode, and this increases
	 * its APIC arbitration priority. To avoid the external timer
	 * IRQ APIC event being in synchron with the APIC clock we
	 * introduce an interrupt skew to spread out timer events.
	 *
	 * The number of slices within a 'big' timeslice is smp_num_cpus+1
	 */

	slice = clocks / (smp_num_cpus+1);
	printk("cpu: %d, clocks: %d, slice: %d\n",
		smp_processor_id(), clocks, slice);

	/*
	 * Wait for IRQ0's slice:
	 */
	wait_8254_wraparound();

	__setup_APIC_LVTT(clocks);

	t0 = apic_read(APIC_TMICT)*APIC_DIVISOR;
	/* Wait till TMCCT gets reloaded from TMICT... */
	do {
		t1 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
		delta = (int)(t0 - t1 - slice*(smp_processor_id()+1));
	} while (delta >= 0);
	/* Now wait for our slice for real. */
	do {
		t1 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
		delta = (int)(t0 - t1 - slice*(smp_processor_id()+1));
	} while (delta < 0);

	__setup_APIC_LVTT(clocks);

	printk("CPU%d<T0:%d,T1:%d,D:%d,S:%d,C:%d>\n",
			smp_processor_id(), t0, t1, delta, slice, clocks);

	__restore_flags(flags);
}
Esempio n. 4
0
static int __init calibrate_APIC_clock(void)
{
    unsigned long long t1 = 0, t2 = 0;
    long tt1, tt2;
    long result;
    int i;
    unsigned long bus_freq; /* KAF: pointer-size avoids compile warns. */
    u32 bus_cycle;          /* length of one bus cycle in pico-seconds */
    const int LOOPS = HZ/10;

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

    /*
     * Put whatever arbitrary (but long enough) timeout
     * value into the APIC clock, we just want to get the
     * counter running for calibration.
     */
    __setup_APIC_LVTT(1000000000);

    /*
     * The timer chip counts down to zero. Let's wait
     * for a wraparound to start exact measurement:
     * (the current tick might have been already half done)
     */
    wait_8254_wraparound();

    /*
     * We wrapped around just now. Let's start:
     */
    if (cpu_has_tsc)
        rdtscll(t1);
    tt1 = apic_read(APIC_TMCCT);

    /*
     * Let's wait LOOPS wraprounds:
     */
    for (i = 0; i < LOOPS; i++)
        wait_8254_wraparound();

    tt2 = apic_read(APIC_TMCCT);
    if (cpu_has_tsc)
        rdtscll(t2);

    /*
     * The APIC bus clock counter is 32 bits only, it
     * might have overflown, but note that we use signed
     * longs, thus no extra care needed.
     *
     * underflown to be exact, as the timer counts down ;)
     */

    result = (tt1-tt2)*APIC_DIVISOR/LOOPS;

    if (cpu_has_tsc)
        apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
                    "%ld.%04ld MHz.\n",
                    ((long)(t2-t1)/LOOPS)/(1000000/HZ),
                    ((long)(t2-t1)/LOOPS)%(1000000/HZ));

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

    /* set up multipliers for accurate timer code */
    bus_freq   = result*HZ;
    bus_cycle  = (u32) (1000000000000LL/bus_freq); /* in pico seconds */
    bus_scale  = (1000*262144)/bus_cycle;

    apic_printk(APIC_VERBOSE, "..... bus_scale = %#x\n", bus_scale);
    /* reset APIC to zero timeout value */
    __setup_APIC_LVTT(0);

    return result;
}
Esempio n. 5
0
int __init calibrate_APIC_clock(void)
{
	unsigned long long t1 = 0, t2 = 0;
	long tt1, tt2;
	long result;
	int i;
	const int LOOPS = HZ/10;

	printk("calibrating APIC timer ...\n");

	/*
	 * Put whatever arbitrary (but long enough) timeout
	 * value into the APIC clock, we just want to get the
	 * counter running for calibration.
	 */
	__setup_APIC_LVTT(1000000000);

	/*
	 * The timer chip counts down to zero. Let's wait
	 * for a wraparound to start exact measurement:
	 * (the current tick might have been already half done)
	 */

	wait_8254_wraparound();

	/*
	 * We wrapped around just now. Let's start:
	 */
	if (cpu_has_tsc)
		rdtscll(t1);
	tt1 = apic_read(APIC_TMCCT);

	/*
	 * Let's wait LOOPS wraprounds:
	 */
	for (i = 0; i < LOOPS; i++)
		wait_8254_wraparound();

	tt2 = apic_read(APIC_TMCCT);
	if (cpu_has_tsc)
		rdtscll(t2);

	/*
	 * The APIC bus clock counter is 32 bits only, it
	 * might have overflown, but note that we use signed
	 * longs, thus no extra care needed.
	 *
	 * underflown to be exact, as the timer counts down ;)
	 */

	result = (tt1-tt2)*APIC_DIVISOR/LOOPS;

	if (cpu_has_tsc)
		printk("..... CPU clock speed is %ld.%04ld MHz.\n",
			((long)(t2-t1)/LOOPS)/(1000000/HZ),
			((long)(t2-t1)/LOOPS)%(1000000/HZ));

	printk("..... host bus clock speed is %ld.%04ld MHz.\n",
		result/(1000000/HZ),
		result%(1000000/HZ));

	return result;
}