.length = sizeof(struct acpi_20_rsdp)
};
-#define ACPI_WAET_RTC_GOOD 0x00000001
-#define ACPI_WAET_PM_TIMER_GOOD 0x00000002
+#define ACPI_WAET_RTC_NO_ACK (1<<0) /* RTC requires no int acknowledge */
+#define ACPI_WAET_TIMER_ONE_READ (1<<1) /* PM timer requires only one read */
-#define ACPI_WAET_FLAGS (ACPI_WAET_RTC_GOOD | \
- ACPI_WAET_PM_TIMER_GOOD)
+/*
+ * The state of the RTC flag getting passed to the guest must be in
+ * sync with the mode selection in the hypervisor RTC emulation code.
+ */
+#define ACPI_WAET_FLAGS (ACPI_WAET_RTC_NO_ACK | \
+ ACPI_WAET_TIMER_ONE_READ)
struct acpi_20_waet Waet = {
.header = {
#define epoch_year 1900
#define get_year(x) (x + epoch_year)
+enum rtc_mode {
+ rtc_mode_no_ack,
+ rtc_mode_strict
+};
+
+/* This must be in sync with how hvmloader sets the ACPI WAET flags. */
+#define mode_is(d, m) ((void)(d), rtc_mode_##m == rtc_mode_no_ack)
+#define rtc_mode_is(s, m) mode_is(vrtc_domain(s), m)
+
static void rtc_copy_date(RTCState *s);
static void rtc_set_time(RTCState *s);
static inline int from_bcd(RTCState *s, int a);
{
ASSERT(spin_is_locked(&s->lock));
- if ( s->hw.cmos_data[RTC_REG_C] & RTC_IRQF )
+ 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 */
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);
}
bool_t ret;
spin_lock(&s->lock);
- ret = !(s->hw.cmos_data[RTC_REG_C] & RTC_IRQF);
- if ( !(s->hw.cmos_data[RTC_REG_C] & RTC_PF) )
+ 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);
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 )
+ 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);