hpet: inverse polarity when pin above ISA_NUM_IRQS

According to hpet spec, hpet irq is high active. But according to
ICH spec, there is inversion before the input of ioapic. So the OS
will expect low active on this IRQ line. (On bare metal, if OS driver
claims high active on this line, spurious irq is generated)

We fold the emulation of this inversion inside the hpet logic.

Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Liu Ping Fan 2013-12-08 17:38:16 +08:00 committed by Michael S. Tsirkin
parent 4c41425d2e
commit 0d63b2dd31
1 changed files with 12 additions and 2 deletions

View File

@ -198,13 +198,23 @@ static void update_irq(struct HPETTimer *timer, int set)
if (!set || !timer_enabled(timer) || !hpet_enabled(timer->state)) {
s->isr &= ~mask;
if (!timer_fsb_route(timer)) {
qemu_irq_lower(s->irqs[route]);
/* fold the ICH PIRQ# pin's internal inversion logic into hpet */
if (route >= ISA_NUM_IRQS) {
qemu_irq_raise(s->irqs[route]);
} else {
qemu_irq_lower(s->irqs[route]);
}
}
} else if (timer_fsb_route(timer)) {
stl_le_phys(timer->fsb >> 32, timer->fsb & 0xffffffff);
} else if (timer->config & HPET_TN_TYPE_LEVEL) {
s->isr |= mask;
qemu_irq_raise(s->irqs[route]);
/* fold the ICH PIRQ# pin's internal inversion logic into hpet */
if (route >= ISA_NUM_IRQS) {
qemu_irq_lower(s->irqs[route]);
} else {
qemu_irq_raise(s->irqs[route]);
}
} else {
s->isr &= ~mask;
qemu_irq_pulse(s->irqs[route]);