diff options
author | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-01-15 20:11:34 +0000 |
---|---|---|
committer | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-01-15 20:11:34 +0000 |
commit | 73822ec806bc8459047b6e9dea71d675c283a84c (patch) | |
tree | 4a7a2c610ba22ddb4a46158f155a798fb74481c8 /hw/apic.c | |
parent | 5fc1503efc552e0ae0d9fec070d5784f51fce6b9 (diff) |
Add -rtc-td-hack option to fix time drift with RTC on Windows (Gleb Natapov)
After my last patch to fix interrupt coalescing was rejected
on the basis that it is too intrusive we decided to make the
fix much more localized and only fix the problem for RTC time
source. Unfortunately it is impossible to fix the problem entirely
inside RTC code like Andrzej proposed since Windows reads RTC
register C more then once on each time interrupt so it is impossible
to count reliably how many interrupt windows actually handled.
Proposed solution is localized to I386 target and is disabled by
default. To enable it "-rtc-td-hack" flag should be used.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6320 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/apic.c')
-rw-r--r-- | hw/apic.c | 22 |
1 files changed, 22 insertions, 0 deletions
@@ -100,6 +100,8 @@ struct IOAPICState { static int apic_io_memory; static APICState *local_apics[MAX_APICS + 1]; static int last_apic_id = 0; +static int apic_irq_delivered; + static void apic_init_ipi(APICState *s); static void apic_set_irq(APICState *s, int vector_num, int trigger_mode); @@ -133,6 +135,14 @@ static inline void reset_bit(uint32_t *tab, int index) tab[i] &= ~mask; } +static inline int get_bit(uint32_t *tab, int index) +{ + int i, mask; + i = index >> 5; + mask = 1 << (index & 0x1f); + return !!(tab[i] & mask); +} + static void apic_local_deliver(CPUState *env, int vector) { APICState *s = env->apic_state; @@ -349,8 +359,20 @@ static void apic_update_irq(APICState *s) cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD); } +void apic_reset_irq_delivered(void) +{ + apic_irq_delivered = 0; +} + +int apic_get_irq_delivered(void) +{ + return apic_irq_delivered; +} + static void apic_set_irq(APICState *s, int vector_num, int trigger_mode) { + apic_irq_delivered += !get_bit(s->irr, vector_num); + set_bit(s->irr, vector_num); if (trigger_mode) set_bit(s->tmr, vector_num); |