Ejemplo n.º 1
0
Archivo: rtc.c Proyecto: 0day-ci/xen
/* Enable/configure/disable the periodic timer based on the RTC_PIE and
 * RTC_RATE_SELECT settings */
static void rtc_timer_update(RTCState *s)
{
    int period_code, period, delta;
    struct vcpu *v = vrtc_vcpu(s);

    ASSERT(spin_is_locked(&s->lock));

    s->pt_dead_ticks = 0;

    period_code = s->hw.cmos_data[RTC_REG_A] & RTC_RATE_SELECT;
    switch ( s->hw.cmos_data[RTC_REG_A] & RTC_DIV_CTL )
    {
    case RTC_REF_CLCK_32KHZ:
        if ( (period_code != 0) && (period_code <= 2) )
            period_code += 7;
        /* fall through */
    case RTC_REF_CLCK_1MHZ:
    case RTC_REF_CLCK_4MHZ:
        if ( period_code != 0 )
        {
            period = 1 << (period_code - 1); /* period in 32 Khz cycles */
            period = DIV_ROUND(period * 1000000000ULL, 32768); /* in ns */
            if ( period != s->period )
            {
                s_time_t now = NOW();

                s->period = period;
                if ( v->domain->arch.hvm_domain.params[HVM_PARAM_VPT_ALIGN] )
                    delta = 0;
                else
                    delta = period - ((now - s->start_time) % period);
                if ( s->hw.cmos_data[RTC_REG_B] & RTC_PIE )
                {
                    TRACE_2D(TRC_HVM_EMUL_RTC_START_TIMER, delta, period);
                    create_periodic_time(v, &s->pt, delta, period,
                                         RTC_IRQ, rtc_pf_callback, s);
                }
                else
                    s->check_ticks_since = now;
            }
            break;
        }
        /* fall through */
    default:
        TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER);
        destroy_periodic_time(&s->pt);
        s->period = 0;
        break;
    }
}
Ejemplo n.º 2
0
/* Enable/configure/disable the periodic timer based on the RTC_PIE and
 * RTC_RATE_SELECT settings */
static void rtc_timer_update(RTCState *s)
{
    int period_code, period, delta;
    struct vcpu *v = vrtc_vcpu(s);

    ASSERT(spin_is_locked(&s->lock));

    s->pt_dead_ticks = 0;

    period_code = s->hw.cmos_data[RTC_REG_A] & RTC_RATE_SELECT;
    switch ( s->hw.cmos_data[RTC_REG_A] & RTC_DIV_CTL )
    {
    case RTC_REF_CLCK_32KHZ:
        if ( (period_code != 0) && (period_code <= 2) )
            period_code += 7;
        /* fall through */
    case RTC_REF_CLCK_1MHZ:
    case RTC_REF_CLCK_4MHZ:
        if ( period_code != 0 )
        {
            if ( period_code != s->pt_code )
            {
                s->pt_code = period_code;
                period = 1 << (period_code - 1); /* period in 32 Khz cycles */
                period = DIV_ROUND(period * 1000000000ULL, 32768); /* in ns */
                if ( v->domain->arch.hvm_domain.params[HVM_PARAM_VPT_ALIGN] )
                    delta = 0;
                else
                    delta = period - ((NOW() - s->start_time) % period);
                create_periodic_time(v, &s->pt, delta, period,
                                     RTC_IRQ, NULL, s);
            }
            break;
        }
        /* fall through */
    default:
        destroy_periodic_time(&s->pt);
        s->pt_code = 0;
        break;
    }
}
Ejemplo n.º 3
0
Archivo: rtc.c Proyecto: HackLinux/xen
/* Enable/configure/disable the periodic timer based on the RTC_PIE and
 * RTC_RATE_SELECT settings */
static void rtc_timer_update(RTCState *s)
{
    int period_code, period;
    struct vcpu *v = vrtc_vcpu(s);

    ASSERT(spin_is_locked(&s->lock));

    period_code = s->hw.cmos_data[RTC_REG_A] & RTC_RATE_SELECT;
    if ( (period_code != 0) && (s->hw.cmos_data[RTC_REG_B] & RTC_PIE) )
    {
        if ( period_code <= 2 )
            period_code += 7;

        period = 1 << (period_code - 1); /* period in 32 Khz cycles */
        period = DIV_ROUND((period * 1000000000ULL), 32768); /* period in ns */
        create_periodic_time(v, &s->pt, period, period, RTC_IRQ,
                             rtc_periodic_cb, s);
    }
    else
    {
        destroy_periodic_time(&s->pt);
    }
}