Exemplo n.º 1
0
Arquivo: rtc.c Projeto: 0day-ci/xen
static void rtc_update_irq(RTCState *s)
{
    ASSERT(spin_is_locked(&s->lock));

    if ( rtc_mode_is(s, strict) && (s->hw.cmos_data[RTC_REG_C] & RTC_IRQF) )
        return;

    /* IRQ is raised if any source is both raised & enabled */
    if ( !(s->hw.cmos_data[RTC_REG_B] &
           s->hw.cmos_data[RTC_REG_C] &
           (RTC_PF | RTC_AF | RTC_UF)) )
        return;

    s->hw.cmos_data[RTC_REG_C] |= RTC_IRQF;
    if ( rtc_mode_is(s, no_ack) )
        hvm_isa_irq_deassert(vrtc_domain(s), RTC_IRQ);
    hvm_isa_irq_assert(vrtc_domain(s), RTC_IRQ);
}
Exemplo n.º 2
0
static uint32_t rtc_ioport_read(RTCState *s, uint32_t addr)
{
    int ret;
    struct domain *d = vrtc_domain(s);

    if ( (addr & 1) == 0 )
        return 0xff;

    spin_lock(&s->lock);

    switch ( s->hw.cmos_index )
    {
    case RTC_SECONDS:
    case RTC_MINUTES:
    case RTC_HOURS:
    case RTC_DAY_OF_WEEK:
    case RTC_DAY_OF_MONTH:
    case RTC_MONTH:
    case RTC_YEAR:
        /* if not in set mode, adjust cmos before reading*/
        if (!(s->hw.cmos_data[RTC_REG_B] & RTC_SET))
        {
            s->current_tm = gmtime(get_localtime(d));
            rtc_copy_date(s);
        }
        ret = s->hw.cmos_data[s->hw.cmos_index];
        break;
    case RTC_REG_A:
        ret = s->hw.cmos_data[s->hw.cmos_index];
        if ((s->use_timer == 0) && update_in_progress(s))
            ret |= RTC_UIP;
        break;
    case RTC_REG_C:
        ret = s->hw.cmos_data[s->hw.cmos_index];
        s->hw.cmos_data[RTC_REG_C] = 0x00;
        if ( (ret & RTC_IRQF) && !rtc_mode_is(s, no_ack) )
            hvm_isa_irq_deassert(d, RTC_IRQ);
        rtc_update_irq(s);
        check_update_timer(s);
        alarm_timer_update(s);
        rtc_timer_update(s);
        break;
    default:
        ret = s->hw.cmos_data[s->hw.cmos_index];
        break;
    }

    spin_unlock(&s->lock);

    return ret;
}
Exemplo n.º 3
0
bool_t rtc_periodic_interrupt(void *opaque)
{
    RTCState *s = opaque;
    bool_t ret;

    spin_lock(&s->lock);
    ret = rtc_mode_is(s, no_ack) || !(s->hw.cmos_data[RTC_REG_C] & RTC_IRQF);
    if ( rtc_mode_is(s, no_ack) || !(s->hw.cmos_data[RTC_REG_C] & RTC_PF) )
    {
        s->hw.cmos_data[RTC_REG_C] |= RTC_PF;
        rtc_update_irq(s);
    }
    else if ( ++(s->pt_dead_ticks) >= 10 )
    {
        /* VM is ignoring its RTC; no point in running the timer */
        destroy_periodic_time(&s->pt);
        s->pt_code = 0;
    }
    if ( !(s->hw.cmos_data[RTC_REG_C] & RTC_IRQF) )
        ret = 0;
    spin_unlock(&s->lock);

    return ret;
}
Exemplo n.º 4
0
Arquivo: rtc.c Projeto: 0day-ci/xen
/* Called by the VPT code after it's injected a PF interrupt for us.
 * Fix up the register state to reflect what happened. */
static void rtc_pf_callback(struct vcpu *v, void *opaque)
{
    RTCState *s = opaque;

    spin_lock(&s->lock);

    if ( !rtc_mode_is(s, no_ack)
         && (s->hw.cmos_data[RTC_REG_C] & RTC_IRQF)
         && ++(s->pt_dead_ticks) >= 10 )
    {
        /* VM is ignoring its RTC; no point in running the timer */
        TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER);
        destroy_periodic_time(&s->pt);
        s->period = 0;
    }

    s->hw.cmos_data[RTC_REG_C] |= RTC_PF|RTC_IRQF;

    spin_unlock(&s->lock);
}