static void rtc_irq_raise(qemu_irq irq) { /* When HPET is operating in legacy mode, RTC interrupts are disabled * We block qemu_irq_raise, but not qemu_irq_lower, in case legacy * mode is established while interrupt is raised. We want it to * be lowered in any case */ #if defined TARGET_I386 || defined TARGET_X86_64 if (!hpet_in_legacy_mode()) #endif qemu_irq_raise(irq); }
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); }
static void rtc_timer_update(RTCState *s, int64_t current_time) { int period_code, period; int64_t cur_clock, next_irq_clock; int enable_pie; period_code = s->cmos_data[RTC_REG_A] & 0x0f; #if defined TARGET_I386 /* disable periodic timer if hpet is in legacy mode, since interrupts are * disabled anyway. */ enable_pie = !hpet_in_legacy_mode(); #else enable_pie = 1; #endif if (period_code != 0 && (((s->cmos_data[RTC_REG_B] & REG_B_PIE) && enable_pie) || ((s->cmos_data[RTC_REG_B] & REG_B_SQWE) && s->sqw_irq))) { 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, get_ticks_per_sec()); next_irq_clock = (cur_clock & ~(period - 1)) + period; s->next_periodic_time = muldiv64(next_irq_clock, get_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); } }