예제 #1
0
static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
{
    RTCState *s = opaque;

    if ((addr & 1) == 0) {
        s->cmos_index = data & 0x7f;
    } else {
        CMOS_DPRINTF("cmos: write index=0x%02x val=0x%02x\n",
                     s->cmos_index, data);
        switch(s->cmos_index) {
        case RTC_SECONDS_ALARM:
        case RTC_MINUTES_ALARM:
        case RTC_HOURS_ALARM:
            /* XXX: not supported */
            s->cmos_data[s->cmos_index] = data;
            break;
        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:
            s->cmos_data[s->cmos_index] = data;
            /* if in set mode, do not update the time */
            if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
                rtc_set_time(s);
            }
            break;
        case RTC_REG_A:
            /* UIP bit is read only */
            s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
                (s->cmos_data[RTC_REG_A] & REG_A_UIP);
            rtc_timer_update(s, qemu_get_clock(rtc_clock));
            break;
        case RTC_REG_B:
            if (data & REG_B_SET) {
                /* set mode: reset UIP mode */
                s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
                data &= ~REG_B_UIE;
            } else {
                /* if disabling set mode, update the time */
                if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
                    rtc_set_time(s);
                }
            }
            s->cmos_data[RTC_REG_B] = data;
            rtc_timer_update(s, qemu_get_clock(rtc_clock));
            break;
        case RTC_REG_C:
        case RTC_REG_D:
            /* cannot write to them */
            break;
        default:
            s->cmos_data[s->cmos_index] = data;
            break;
        }
    }
}
예제 #2
0
파일: rtc.c 프로젝트: 0day-ci/xen
/* Reload the hardware state from a saved domain */
static int rtc_load(struct domain *d, hvm_domain_context_t *h)
{
    RTCState *s = domain_vrtc(d);

    if ( !has_vrtc(d) )
        return -ENODEV;

    spin_lock(&s->lock);

    /* Restore the registers */
    if ( hvm_load_entry(RTC, h, &s->hw) != 0 )
    {
        spin_unlock(&s->lock);
        return -EINVAL;
    }

    /* Reset the wall-clock time.  In normal running, this runs with host 
     * time, so let's keep doing that. */
    s->current_tm = gmtime(get_localtime(d));
    rtc_copy_date(s);

    /* Reset the periodic interrupt timer based on the registers */
    rtc_timer_update(s);
    check_update_timer(s);
    alarm_timer_update(s);

    spin_unlock(&s->lock);

    return 0;
}
예제 #3
0
static void rtc_periodic_timer(void *opaque)
{
    RTCState *s = opaque;

    rtc_timer_update(s, s->next_periodic_time);
    if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
        s->cmos_data[RTC_REG_C] |= 0xc0;
#ifdef TARGET_I386
        if(rtc_td_hack) {
            if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
                s->irq_reinject_on_ack_count = 0;		
            apic_reset_irq_delivered();
            qemu_irq_raise(s->irq);
            if (!apic_get_irq_delivered()) {
                s->irq_coalesced++;
                rtc_coalesced_timer_update(s);
                DPRINTF_C("cmos: coalesced irqs increased to %d\n",
                          s->irq_coalesced);
            }
        } else
#endif
        qemu_irq_raise(s->irq);
    }
    if (s->cmos_data[RTC_REG_B] & REG_B_SQWE) {
        /* Not square wave at all but we don't want 2048Hz interrupts!
           Must be seen as a pulse.  */
        qemu_irq_raise(s->sqw_irq);
    }
}
예제 #4
0
static void rtc_periodic_timer(void *opaque)
{
    RTCState *s = opaque;

    rtc_timer_update(s, s->next_periodic_time);
    if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
        s->cmos_data[RTC_REG_C] |= 0xc0;
#ifdef TARGET_I386
        if(rtc_td_hack) {
            apic_reset_irq_delivered();
            rtc_irq_raise(s->irq);
            if (!apic_get_irq_delivered()) {
                s->irq_coalesced++;
                rtc_coalesced_timer_update(s);
            }
        } else
#endif
        rtc_irq_raise(s->irq);
    }
    if (s->cmos_data[RTC_REG_B] & REG_B_SQWE) {
        /* Not square wave at all but we don't want 2048Hz interrupts!
           Must be seen as a pulse.  */
        qemu_irq_raise(s->sqw_irq);
    }
}
예제 #5
0
void rtc_callback(void *arg){
	rtc_timer_update(true);
	if(soft_watchdog > 0){
		soft_watchdog--;
		if(soft_watchdog == 0)
			system_restart();
	}
}
예제 #6
0
파일: rtc.c 프로젝트: CrazyXen/XEN_CODE
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;
}
예제 #7
0
파일: mc146818rtc.c 프로젝트: ddk50/ibkvm
static void rtc_timer_update(RTCState *s, int64_t current_time)
{
    int period_code, period;
    int64_t cur_clock, next_irq_clock;

    period_code = s->cmos_data[RTC_REG_A] & 0x0f;
#if defined TARGET_I386 || defined TARGET_X86_64
    /* disable periodic timer if hpet is in legacy mode, since interrupts are
     * disabled anyway.
     */
    if (period_code != 0 && (s->cmos_data[RTC_REG_B] & REG_B_PIE) && !hpet_in_legacy_mode()) {
#else
    if (period_code != 0 && (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
#endif
        if (period_code <= 2)
            period_code += 7;
        /* period in 32 Khz cycles */
        period = 1 << (period_code - 1);
#ifdef TARGET_I386
        if(period != s->period)
            s->irq_coalesced = (s->irq_coalesced * s->period) / period;
        s->period = period;
#endif
        /* compute 32 khz clock */
        cur_clock = muldiv64(current_time, 32768, ticks_per_sec);
        next_irq_clock = (cur_clock & ~(period - 1)) + period;
        s->next_periodic_time = muldiv64(next_irq_clock, ticks_per_sec, 32768) + 1;
        qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
    } else {
#ifdef TARGET_I386
        s->irq_coalesced = 0;
#endif
        qemu_del_timer(s->periodic_timer);
    }
}

static void rtc_periodic_timer(void *opaque)
{
    RTCState *s = opaque;

    rtc_timer_update(s, s->next_periodic_time);
#ifdef TARGET_I386
    if ((s->cmos_data[RTC_REG_C] & 0xc0) && rtc_td_hack) {
        s->irq_coalesced++;
        return;
    }
#endif
    s->cmos_data[RTC_REG_C] |= 0xc0;
    rtc_irq_raise(s->irq);
}
예제 #8
0
static void rtc_notify_clock_reset(Notifier *notifier, void *data)
{
    RTCState *s = container_of(notifier, RTCState, clock_reset_notifier);
    int64_t now = *(int64_t *)data;

    rtc_set_date_from_host(&s->dev);
    s->next_second_time = now + (get_ticks_per_sec() * 99) / 100;
    qemu_mod_timer(s->second_timer2, s->next_second_time);
    rtc_timer_update(s, now);
#ifdef TARGET_I386
    if (rtc_td_hack) {
        rtc_coalesced_timer_update(s);
    }
#endif
}
예제 #9
0
// Lua: tmr.time() , return rtc time in second
static int tmr_time( lua_State* L ){
	uint64_t us=rtc_timer_update(false);
	lua_pushinteger(L, us/1000000);
	return 1; 
}
예제 #10
0
파일: rtc.c 프로젝트: 0day-ci/xen
static int rtc_ioport_write(void *opaque, uint32_t addr, uint32_t data)
{
    RTCState *s = opaque;
    struct domain *d = vrtc_domain(s);
    uint32_t orig;

    spin_lock(&s->lock);

    if ( (addr & 1) == 0 )
    {
        data &= 0x7f;
        s->hw.cmos_index = data;
        spin_unlock(&s->lock);
        return (data < RTC_CMOS_SIZE);
    }

    if ( s->hw.cmos_index >= RTC_CMOS_SIZE )
    {
        spin_unlock(&s->lock);
        return 0;
    }

    orig = s->hw.cmos_data[s->hw.cmos_index];
    switch ( s->hw.cmos_index )
    {
    case RTC_SECONDS_ALARM:
    case RTC_MINUTES_ALARM:
    case RTC_HOURS_ALARM:
        s->hw.cmos_data[s->hw.cmos_index] = data;
        alarm_timer_update(s);
        break;
    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 in set mode, just write the register */
        if ( (s->hw.cmos_data[RTC_REG_B] & RTC_SET) )
            s->hw.cmos_data[s->hw.cmos_index] = data;
        else
        {
            /* Fetch the current time and update just this field. */
            s->current_tm = gmtime(get_localtime(d));
            rtc_copy_date(s);
            s->hw.cmos_data[s->hw.cmos_index] = data;
            rtc_set_time(s);
        }
        alarm_timer_update(s);
        break;
    case RTC_REG_A:
        /* UIP bit is read only */
        s->hw.cmos_data[RTC_REG_A] = (data & ~RTC_UIP) | (orig & RTC_UIP);
        if ( (data ^ orig) & ~RTC_UIP )
            rtc_timer_update(s);
        break;
    case RTC_REG_B:
        if ( data & RTC_SET )
        {
            /* set mode: reset UIP mode */
            s->hw.cmos_data[RTC_REG_A] &= ~RTC_UIP;
            /* adjust cmos before stopping */
            if (!(orig & RTC_SET))
            {
                s->current_tm = gmtime(get_localtime(d));
                rtc_copy_date(s);
            }
        }
        else
        {
            /* if disabling set mode, update the time */
            if ( orig & RTC_SET )
                rtc_set_time(s);
        }
        check_for_pf_ticks(s);
        s->hw.cmos_data[RTC_REG_B] = data;
        /*
         * If the interrupt is already set when the interrupt becomes
         * enabled, raise an interrupt immediately.
         */
        rtc_update_irq(s);
        if ( (data ^ orig) & RTC_PIE )
        {
            TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER);
            destroy_periodic_time(&s->pt);
            s->period = 0;
            rtc_timer_update(s);
        }
        if ( (data ^ orig) & RTC_SET )
            check_update_timer(s);
        if ( (data ^ orig) & (RTC_24H | RTC_DM_BINARY | RTC_SET) )
            alarm_timer_update(s);
        break;
    case RTC_REG_C:
    case RTC_REG_D:
        /* cannot write to them */
        break;
    }

    spin_unlock(&s->lock);

    return 1;
}
예제 #11
0
파일: rtc.c 프로젝트: HackLinux/xen
static int rtc_ioport_write(void *opaque, uint32_t addr, uint32_t data)
{
    RTCState *s = opaque;
    struct domain *d = vrtc_domain(s);
    uint32_t orig;

    spin_lock(&s->lock);

    if ( (addr & 1) == 0 )
    {
        data &= 0x7f;
        s->hw.cmos_index = data;
        spin_unlock(&s->lock);
        return (data < RTC_CMOS_SIZE);
    }

    if ( s->hw.cmos_index >= RTC_CMOS_SIZE )
    {
        spin_unlock(&s->lock);
        return 0;
    }

    orig = s->hw.cmos_data[s->hw.cmos_index];
    switch ( s->hw.cmos_index )
    {
    case RTC_SECONDS_ALARM:
    case RTC_MINUTES_ALARM:
    case RTC_HOURS_ALARM:
        s->hw.cmos_data[s->hw.cmos_index] = data;
        alarm_timer_update(s);
        break;
    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:
        s->hw.cmos_data[s->hw.cmos_index] = data;
        /* if in set mode, do not update the time */
        if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) )
            rtc_set_time(s);
        alarm_timer_update(s);
        break;
    case RTC_REG_A:
        /* UIP bit is read only */
        s->hw.cmos_data[RTC_REG_A] = (data & ~RTC_UIP) | (orig & RTC_UIP);
        if ( (data ^ orig) & ~RTC_UIP )
            rtc_timer_update(s);
        break;
    case RTC_REG_B:
        if ( data & RTC_SET )
        {
            /* set mode: reset UIP mode */
            s->hw.cmos_data[RTC_REG_A] &= ~RTC_UIP;
            /* adjust cmos before stopping */
            if (!(s->hw.cmos_data[RTC_REG_B] & RTC_SET))
            {
                s->current_tm = gmtime(get_localtime(d));
                rtc_copy_date(s);
            }
        }
        else
        {
            /* if disabling set mode, update the time */
            if ( s->hw.cmos_data[RTC_REG_B] & RTC_SET )
                rtc_set_time(s);
        }
        /* if the interrupt is already set when the interrupt become
         * enabled, raise an interrupt immediately*/
        if ((data & RTC_UIE) && !(s->hw.cmos_data[RTC_REG_B] & RTC_UIE))
            if (s->hw.cmos_data[RTC_REG_C] & RTC_UF)
            {
                hvm_isa_irq_deassert(d, RTC_IRQ);
                hvm_isa_irq_assert(d, RTC_IRQ);
            }
        s->hw.cmos_data[RTC_REG_B] = data;
        if ( (data ^ orig) & RTC_PIE )
            rtc_timer_update(s);
        check_update_timer(s);
        alarm_timer_update(s);
        break;
    case RTC_REG_C:
    case RTC_REG_D:
        /* cannot write to them */
        break;
    }

    spin_unlock(&s->lock);

    return 1;
}