Пример #1
0
static uint64_t calculate_next(struct AspeedTimer *t)
{
    uint64_t next = 0;
    uint32_t rate = calculate_rate(t);

    while (!next) {
        /* We don't know the relationship between the values in the match
         * registers, so sort using MAX/MIN/zero. We sort in that order as the
         * timer counts down to zero. */
        uint64_t seq[] = {
            calculate_time(t, MAX(t->match[0], t->match[1])),
            calculate_time(t, MIN(t->match[0], t->match[1])),
            calculate_time(t, 0),
        };
        uint64_t reload_ns;
        uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);

        if (now < seq[0]) {
            next = seq[0];
        } else if (now < seq[1]) {
            next = seq[1];
        } else if (now < seq[2]) {
            next = seq[2];
        } else if (t->reload) {
            reload_ns = muldiv64(t->reload, NANOSECONDS_PER_SECOND, rate);
            t->start = now - ((now - t->start) % reload_ns);
        } else {
            /* no reload value, return 0 */
            break;
        }
    }

    return next;
}
Пример #2
0
static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns)
{
    uint64_t delta_ns = now_ns - MIN(now_ns, t->start);
    uint32_t rate = calculate_rate(t);
    uint64_t ticks = muldiv64(delta_ns, rate, NANOSECONDS_PER_SECOND);

    return t->reload - MIN(t->reload, ticks);
}
Пример #3
0
static inline uint64_t calculate_time(struct AspeedTimer *t, uint32_t ticks)
{
    uint64_t delta_ns;
    uint64_t delta_ticks;

    delta_ticks = t->reload - MIN(t->reload, ticks);
    delta_ns = muldiv64(delta_ticks, NANOSECONDS_PER_SECOND, calculate_rate(t));

    return t->start + delta_ns;
}
GHOST_TSuccess
GHOST_DisplayManagerX11::
getDisplaySetting(
		GHOST_TUns8 display,
		GHOST_TInt32 index,
		GHOST_DisplaySetting& setting) const
{
	Display *dpy = m_system->getXDisplay();

	if (dpy == NULL)
		return GHOST_kFailure;

	(void)display;

#ifdef WITH_X11_XF86VMODE
	int majorVersion, minorVersion;

	GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");

	majorVersion = minorVersion = 0;
	if (XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
		XF86VidModeModeInfo **vidmodes;
		int numSettings;

		if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) {
			GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n");

			setting.xPixels = vidmodes[index]->hdisplay;
			setting.yPixels = vidmodes[index]->vdisplay;
			setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
			setting.frequency = calculate_rate(vidmodes[index]);
			XFree(vidmodes);

			return GHOST_kSuccess;
		}
	}
	else {
		fprintf(stderr, "Warning: XF86VidMode extension missing!\n");
		/* fallback to non xf86vmode below */
	}
#endif  /* WITH_X11_XF86VMODE */

	GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
	GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n");
	(void)index;

	setting.xPixels  = DisplayWidth(dpy, DefaultScreen(dpy));
	setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy));
	setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
	setting.frequency = 60.0f;

	return GHOST_kSuccess;
}
Пример #5
0
void TestZeroRateWith32BitsCounter(CuTest *tc)
{
        time_t cur_time = time(NULL);
        time_t prev_time = cur_time - 60;
        unsigned long long prev_counter = 1000000;
        unsigned long long cur_counter = prev_counter;

        unsigned long long counter_diff;
        unsigned rate;
        calculate_rate(prev_time, prev_counter, cur_time, cur_counter, 32, &counter_diff, &rate);

        CuAssertIntEquals(tc, 0u, counter_diff);
        CuAssertIntEquals(tc, 0u, rate);
}
Пример #6
0
void TestGaugeValueChanged(CuTest *tc)
{
        time_t cur_time = time(NULL);
        time_t prev_time = cur_time - 60;
        unsigned long long prev_counter = 1000000;
        unsigned long long cur_counter = 1000000 + 1000;

        unsigned long long counter_diff;
        unsigned rate;
        calculate_rate(prev_time, prev_counter, cur_time, cur_counter, 0, &counter_diff, &rate);

        CuAssertIntEquals(tc, 1000000u + 1000, counter_diff);
        CuAssertIntEquals(tc, 1000000u + 1000, rate);
}
Пример #7
0
void TestOneKbpsRateWith64BitsCounterThatWraps(CuTest *tc)
{
        time_t cur_time = time(NULL);
        time_t prev_time = cur_time - 60;
        unsigned long long prev_counter = 18446744073709551000ull;
        unsigned long long cur_counter = prev_counter + 60 * 1000 / 8;

        unsigned long long counter_diff;
        unsigned rate;
        calculate_rate(prev_time, prev_counter, cur_time, cur_counter, 64, &counter_diff, &rate);

        CuAssertIntEquals(tc, 60u * 1000 / 8, counter_diff);
        CuAssertIntEquals(tc, 1000u / 8, rate);
}
Пример #8
0
void TestOneKbpsRateWith32BitsCounterThatWraps(CuTest *tc)
{
        time_t cur_time = time(NULL);
        time_t prev_time = cur_time - 60;
        unsigned int prev_counter = 4294967000u;
        unsigned int cur_counter = prev_counter + 60 * 1000 / 8;

        unsigned long long counter_diff;
        unsigned rate;
        calculate_rate(prev_time, prev_counter, cur_time, cur_counter, 32, &counter_diff, &rate);

        CuAssertIntEquals(tc, 60u * 1000 / 8, counter_diff);
        CuAssertIntEquals(tc, 1000u / 8, rate);
}
Пример #9
0
static void aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg,
                                   uint32_t value)
{
    AspeedTimer *t;
    uint32_t old_reload;

    trace_aspeed_timer_set_value(timer, reg, value);
    t = &s->timers[timer];
    switch (reg) {
    case TIMER_REG_RELOAD:
        old_reload = t->reload;
        t->reload = value;

        /* If the reload value was not previously set, or zero, and
         * the current value is valid, try to start the timer if it is
         * enabled.
         */
        if (old_reload || !t->reload) {
            break;
        }

    case TIMER_REG_STATUS:
        if (timer_enabled(t)) {
            uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
            int64_t delta = (int64_t) value - (int64_t) calculate_ticks(t, now);
            uint32_t rate = calculate_rate(t);

            t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate);
            aspeed_timer_mod(t);
        }
        break;
    case TIMER_REG_MATCH_FIRST:
    case TIMER_REG_MATCH_SECOND:
        t->match[reg - 2] = value;
        if (timer_enabled(t)) {
            aspeed_timer_mod(t);
        }
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "%s: Programming error: unexpected reg: %d\n",
                      __func__, reg);
        break;
    }
}
Пример #10
0
GHOST_TSuccess
GHOST_DisplayManagerX11::
setCurrentDisplaySetting(
		GHOST_TUns8 /*display*/,
		const GHOST_DisplaySetting& setting)
{
#ifdef WITH_X11_XF86VMODE
	/* Mode switching code ported from SDL:
	 * See: src/video/x11/SDL_x11modes.c:set_best_resolution
	 */
	int majorVersion, minorVersion;
	XF86VidModeModeInfo **vidmodes;
	Display *dpy = m_system->getXDisplay();
	int scrnum, num_vidmodes;

	if (dpy == NULL)
		return GHOST_kFailure;

	scrnum = DefaultScreen(dpy);

	/* Get video mode list */
	majorVersion = minorVersion = 0;
	if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
		fprintf(stderr, "Error: XF86VidMode extension missing!\n");
		return GHOST_kFailure;
	}
#  ifdef DEBUG
	printf("Using XFree86-VidModeExtension Version %d.%d\n",
	       majorVersion, minorVersion);
#  endif

	if (XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes)) {
		int best_fit = -1;

		for (int i = 0; i < num_vidmodes; i++) {
			if (vidmodes[i]->hdisplay < setting.xPixels ||
			    vidmodes[i]->vdisplay < setting.yPixels)
			{
				continue;
			}

			if (best_fit == -1 ||
			    (vidmodes[i]->hdisplay < vidmodes[best_fit]->hdisplay) ||
			    (vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay &&
			     vidmodes[i]->vdisplay < vidmodes[best_fit]->vdisplay))
			{
				best_fit = i;
				continue;
			}

			if ((vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay) &&
			    (vidmodes[i]->vdisplay == vidmodes[best_fit]->vdisplay))
			{
				if (!setting.frequency) {
					/* Higher is better, right? */
					if (calculate_rate(vidmodes[i]) >
					    calculate_rate(vidmodes[best_fit]))
					{
						best_fit = i;
					}
				}
				else {
					if (abs(calculate_rate(vidmodes[i]) - (int)setting.frequency) <
					    abs(calculate_rate(vidmodes[best_fit]) - (int)setting.frequency))
					{
						best_fit = i;
					}
				}
			}
		}

		if (best_fit != -1) {
#  ifdef DEBUG
			printf("Switching to video mode %dx%d %dx%d %d\n",
			       vidmodes[best_fit]->hdisplay, vidmodes[best_fit]->vdisplay,
			       vidmodes[best_fit]->htotal, vidmodes[best_fit]->vtotal,
			       calculate_rate(vidmodes[best_fit]));
#  endif

			/* change to the mode */
			XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);

			/* Move the viewport to top left */
			XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
		}

		XFree(vidmodes);
	}
	else {
		return GHOST_kFailure;
	}

	XFlush(dpy);
	return GHOST_kSuccess;

#else
	/* Just pretend the request was successful. */
	return GHOST_kSuccess;
#endif
}