Пример #1
0
static void aspeed_timer_expire(void *opaque)
{
    AspeedTimer *t = opaque;
    bool interrupt = false;
    uint32_t ticks;

    if (!timer_enabled(t)) {
        return;
    }

    ticks = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));

    if (!ticks) {
        interrupt = timer_overflow_interrupt(t) || !t->match[0] || !t->match[1];
    } else if (ticks <= MIN(t->match[0], t->match[1])) {
        interrupt = true;
    } else if (ticks <= MAX(t->match[0], t->match[1])) {
        interrupt = true;
    }

    if (interrupt) {
        t->level = !t->level;
        qemu_set_irq(t->irq, t->level);
    }

    aspeed_timer_mod(t);
}
Пример #2
0
static int
calculate_log_ticks (double min, double max, double distance, TICKS * ticks)
{	int k = 0 ;	/* Number of ticks we have placed in "ticks" array */
	double underpinning ; 	/* Largest power of ten that is <= min */

	/* If the interval is less than a decade, just apply the same
	** numbering-choosing scheme as used with linear axis, with the
	** ticks positioned logarithmically.
	*/
	if (max / min < 10.0)
		return calculate_ticks (min, max, distance, 2, ticks) ;

	/* If the range is greater than 1 to 1000000, it will generate more than
	** 19 ticks.  Better to fail explicitly than to overflow.
	*/
	if (max / min > 1000000)
	{	printf ("Error: Frequency range is too great for logarithmic scale.\n") ;
		exit (1) ;
		} ;

	/* First hack: label the powers of ten. */

 	/* Find largest power of ten that is <= minimum value */
	underpinning = pow (10.0, floor (log10 (min))) ;

	/* Go powering up by 10 from there, numbering as we go. */
	k = add_log_ticks (min, max, distance, ticks, k, underpinning, true) ;

	/* Do we have enough numbers? If so, add numberless ticks at 2 and 5 */
	if (k >= TARGET_DIVISIONS + 1) /* Number of labels is n.of divisions + 1 */
	{
		k = add_log_ticks (min, max, distance, ticks, k, underpinning * 2.0, false) ;
		k = add_log_ticks (min, max, distance, ticks, k, underpinning * 5.0, false) ;
		}
	else
	{	int i ;
		/* Not enough numbers: add numbered ticks at 2 and 5 and
		 * unnumbered ticks at all the rest */
		for (i = 2 ; i <= 9 ; i++)
			k = add_log_ticks (min, max, distance, ticks, k,
								underpinning * (1.0 * i), i == 2 || i == 5) ;
		} ;

	/* Greatest possible number of ticks calculation:
	** The worst case is when the else clause adds 8 ticks with the maximal
	** number of divisions, which is when k == TARGET_DIVISIONS, 3,
	** for example 100, 1000, 10000.
	** The else clause adds another 8 ticks inside each division as well as
	** up to 8 ticks after the last number (from 20000 to 90000)
	** and 8 before to the first (from 20 to 90 in the example).
	** Maximum possible ticks is 3+8+8+8+8=35
	*/

	return k ;
} /* calculate_log_ticks */
Пример #3
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;
    }
}
Пример #4
0
static void
render_heat_border (cairo_surface_t * surface, double magfloor, const RECT *r)
{
	const char *decibels = "dB" ;
	char text [512] ;
	cairo_t * cr ;
	cairo_text_extents_t extents ;
	TICKS ticks ;
	int k, tick_count ;

	cr = cairo_create (surface) ;

	cairo_set_source_rgb (cr, 1.0, 1.0, 1.0) ;
	cairo_set_line_width (cr, BORDER_LINE_WIDTH) ;

	/* Border around actual spectrogram. */
	cairo_rectangle (cr, r->left, r->top, r->width, r->height) ;
	cairo_stroke (cr) ;

	cairo_select_font_face (cr, font_family, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL) ;
	cairo_set_font_size (cr, 1.0 * NORMAL_FONT_SIZE) ;

	cairo_text_extents (cr, decibels, &extents) ;
	cairo_move_to (cr, r->left + (r->width - extents.width) / 2, r->top - 5) ;
	cairo_show_text (cr, decibels) ;

	tick_count = calculate_ticks (0.0, fabs (magfloor), r->height, false, &ticks) ;
	for (k = 0 ; k < tick_count ; k++)
	{	x_line (cr, r->left + r->width, r->top + ticks.distance [k], TICK_LEN) ;
		if (JUST_A_TICK (ticks, k))
			continue ;

		str_print_value (text, sizeof (text), -1.0 * ticks.value [k],
			ticks.decimal_places_to_print) ;
		cairo_text_extents (cr, text, &extents) ;
		cairo_move_to (cr, r->left + r->width + 2 * TICK_LEN, r->top + ticks.distance [k] + extents.height / 4.5) ;
		cairo_show_text (cr, text) ;
		} ;

	cairo_destroy (cr) ;
} /* render_heat_border */
Пример #5
0
static uint64_t aspeed_timer_get_value(AspeedTimer *t, int reg)
{
    uint64_t value;

    switch (reg) {
    case TIMER_REG_STATUS:
        value = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
        break;
    case TIMER_REG_RELOAD:
        value = t->reload;
        break;
    case TIMER_REG_MATCH_FIRST:
    case TIMER_REG_MATCH_SECOND:
        value = t->match[reg - 2];
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "%s: Programming error: unexpected reg: %d\n",
                      __func__, reg);
        value = 0;
        break;
    }
    return value;
}
Пример #6
0
static void
render_spect_border (cairo_surface_t * surface, const char * filename, double left, double width, double seconds, double top, double height, double min_freq, double max_freq, bool log_freq)
{
	char text [512] ;
	cairo_t * cr ;
	cairo_text_extents_t extents ;
	cairo_matrix_t matrix ;

	TICKS ticks ;
	int k, tick_count ;

	cr = cairo_create (surface) ;

	cairo_set_source_rgb (cr, 1.0, 1.0, 1.0) ;
	cairo_set_line_width (cr, BORDER_LINE_WIDTH) ;

	/* Print title. */
	cairo_select_font_face (cr, font_family, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL) ;
	cairo_set_font_size (cr, 1.0 * TITLE_FONT_SIZE) ;

	snprintf (text, sizeof (text), "Spectrogram: %s", filename) ;
	cairo_text_extents (cr, text, &extents) ;
	cairo_move_to (cr, left + 2, top - extents.height / 2) ;
	cairo_show_text (cr, text) ;

	/* Print labels. */
	cairo_select_font_face (cr, font_family, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL) ;
	cairo_set_font_size (cr, 1.0 * NORMAL_FONT_SIZE) ;

	/* Border around actual spectrogram. */
	cairo_rectangle (cr, left, top, width, height) ;

	/* Put ticks on Time axis */
	tick_count = calculate_ticks (0.0, seconds, width, false, &ticks) ;
	for (k = 0 ; k < tick_count ; k++)
	{	y_line (cr, left + ticks.distance [k], top + height, TICK_LEN) ;
		if (JUST_A_TICK (ticks, k))
			continue ;
		str_print_value (text, sizeof (text), ticks.value [k],
			ticks.decimal_places_to_print) ;
		cairo_text_extents (cr, text, &extents) ;
		cairo_move_to (cr, left + ticks.distance [k] - extents.width / 2, top + height + 8 + extents.height) ;
		cairo_show_text (cr, text) ;
		} ;

	/* Put ticks on Frequency axis */
	tick_count = calculate_ticks (min_freq, max_freq, height, log_freq, &ticks) ;
	for (k = 0 ; k < tick_count ; k++)
	{	x_line (cr, left + width, top + height - ticks.distance [k], TICK_LEN) ;
		if (JUST_A_TICK (ticks, k))
			continue ;
		str_print_value (text, sizeof (text), ticks.value [k],
			ticks.decimal_places_to_print) ;
		cairo_text_extents (cr, text, &extents) ;
		cairo_move_to (cr, left + width + 12, top + height - ticks.distance [k] + extents.height / 4.5) ;
		cairo_show_text (cr, text) ;
		} ;

	cairo_set_font_size (cr, 1.0 * NORMAL_FONT_SIZE) ;

	/* Label X axis. */
	snprintf (text, sizeof (text), "Time (secs)") ;
	cairo_text_extents (cr, text, &extents) ;
	cairo_move_to (cr, left + (width - extents.width) / 2, cairo_image_surface_get_height (surface) - 8) ;
	cairo_show_text (cr, text) ;

	/* Label Y axis (rotated). */
	snprintf (text, sizeof (text), "Frequency (Hz)") ;
	cairo_text_extents (cr, text, &extents) ;

	cairo_get_font_matrix (cr, &matrix) ;
	cairo_matrix_rotate (&matrix, -0.5 * M_PI) ;
	cairo_set_font_matrix (cr, &matrix) ;

	cairo_move_to (cr, cairo_image_surface_get_width (surface) - 12, top + (height + extents.width) / 2) ;
	cairo_show_text (cr, text) ;

	cairo_destroy (cr) ;
} /* render_spect_border */