コード例 #1
0
ファイル: acpi_timer.c プロジェクト: wan721/DragonFlyBSD
static int
acpi_timer_test(void)
{
    uint32_t	last, this;
    int		min, max, max2, n, delta;
    register_t	s;

    min = INT32_MAX;
    max = max2 = 0;

    /* Test the timer with interrupts disabled to get accurate results. */
#if defined(__i386__)
    s = read_eflags();
#elif defined(__x86_64__)
    s = read_rflags();
#else
#error "no read_eflags"
#endif
    cpu_disable_intr();
    AcpiGetTimer(&last);
    for (n = 0; n < 2000; n++) {
	AcpiGetTimer(&this);
	delta = acpi_TimerDelta(this, last);
	if (delta > max) {
	    max2 = max;
	    max = delta;
	} else if (delta > max2) {
	    max2 = delta;
	}
	if (delta < min)
	    min = delta;
	last = this;
    }
#if defined(__i386__)
    write_eflags(s);
#elif defined(__x86_64__)
    write_rflags(s);
#else
#error "no read_eflags"
#endif

    delta = max2 - min;
    if ((max - min > 8 || delta > 3) && vmm_guest == VMM_GUEST_NONE)
	n = 0;
    else if (min < 0 || max == 0 || max2 == 0)
	n = 0;
    else
	n = 1;
    if (bootverbose) {
	kprintf("ACPI timer looks %s min = %d, max = %d, width = %d\n",
		n ? "GOOD" : "BAD ",
		min, max, max - min);
    }

    return (n);
}
コード例 #2
0
ファイル: acpi_timer.c プロジェクト: wan721/DragonFlyBSD
static sysclock_t
acpi_timer_get_timecount(void)
{
    sysclock_t counter;

    AcpiGetTimer(&counter);
    return (counter + acpi_cputimer.base);
}
コード例 #3
0
u_int
acpitimer_read_fast(struct timecounter *tc)
{
	uint32_t t;

	(void)AcpiGetTimer(&t);

	return t;
}
コード例 #4
0
/*
 * Some chipsets (PIIX4 variants) do not latch correctly;
 * there is a chance that a transition is hit.
 */
u_int
acpitimer_read_safe(struct timecounter *tc)
{
	uint32_t t1, t2, t3;

	(void)AcpiGetTimer(&t2);
	(void)AcpiGetTimer(&t3);

	do {
		t1 = t2;
		t2 = t3;

		(void)AcpiGetTimer(&t3);

	} while ((t1 > t2) || (t2 > t3));

	return t2;
}
コード例 #5
0
static int
acpitimer_test(void)
{
	uint32_t last, this, delta;
	int minl, maxl, n;

	minl = 10000000;
	maxl = 0;

	acpi_md_OsDisableInterrupt();

	(void)AcpiGetTimer(&last);

	for (n = 0; n < N; n++) {

		(void)AcpiGetTimer(&this);

		delta = acpitimer_delta(this, last);

		if (delta > maxl)
			maxl = delta;
		else if (delta < minl)
			minl = delta;

		last = this;
	}

	acpi_md_OsEnableInterrupt();

	if (maxl - minl > 2 )
		n = 0;
	else if (minl < 0 || maxl == 0)
		n = 0;
	else
		n = 1;

	return n;
}
コード例 #6
0
ファイル: acpi_timer.c プロジェクト: wan721/DragonFlyBSD
/*
 * Fetch current time value from reliable hardware.
 *
 * The cputimer interface requires a 32 bit return value.  If the ACPI timer
 * is only 24 bits then we have to keep track of the upper 8 bits on our
 * own.
 *
 * XXX we could probably get away with using a per-cpu field for this and
 * just use interrupt disablement instead of clock_lock.
 */
static sysclock_t
acpi_timer_get_timecount24(void)
{
    sysclock_t counter;

    clock_lock();
    AcpiGetTimer(&counter);
    if (counter < acpi_last_counter)
	acpi_cputimer.base += 0x01000000;
    acpi_last_counter = counter;
    counter += acpi_cputimer.base;
    clock_unlock();
    return (counter);
}
コード例 #7
0
ファイル: acpi_timer.c プロジェクト: wan721/DragonFlyBSD
/*
 * Fetch current time value from hardware that may not correctly
 * latch the counter.  We need to read until we have three monotonic
 * samples and then use the middle one, otherwise we are not protected
 * against the fact that the bits can be wrong in two directions.  If
 * we only cared about monosity, two reads would be enough.
 */
static sysclock_t
acpi_timer_get_timecount_safe(void)
{
    u_int u1, u2, u3;

    if (acpi_timer_resolution != 32)
	clock_lock();

    AcpiGetTimer(&u2);
    AcpiGetTimer(&u3);
    do {
	u1 = u2;
	u2 = u3;
	AcpiGetTimer(&u3);
    } while (u1 > u2 || u2 > u3);

    if (acpi_timer_resolution != 32) {
	if (u2 < acpi_last_counter)
	    acpi_cputimer.base += 0x01000000;
	acpi_last_counter = u2;
	clock_unlock();
    }
    return (u2 + acpi_cputimer.base);
}