From 0d63b2dd31464cfccc80bbeedc24e3863fe4c895 Mon Sep 17 00:00:00 2001 From: Liu Ping Fan Date: Sun, 8 Dec 2013 17:38:16 +0800 Subject: 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 Reviewed-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/timer/hpet.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'hw/timer') diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 2eb75ea945..0aee2c1c41 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -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]); -- cgit v1.2.1 From 7a10ef51c2397ac4323bc786af02c58b413b5cd2 Mon Sep 17 00:00:00 2001 From: Liu Ping Fan Date: Sun, 8 Dec 2013 17:38:17 +0800 Subject: hpet: enable to entitle more irq pins for hpet Owning to some different hardware design, piix and q35 need different compat. So making them diverge. On q35, IRQ2/8 can be reserved for hpet timer 0/1. And pin 16~23 can be assigned to hpet as guest chooses. So we introduce intcap property to do that. Consider the compat and piix/q35, we finally have the following value for intcap: For piix, hpet's intcap is hard coded as IRQ2. For pc-q35-1.7 and earlier, we use IRQ2 for compat reason. Otherwise IRQ2, IRQ8, and IRQ16~23 are allowed. Signed-off-by: Liu Ping Fan Reviewed-by: Michael S. Tsirkin Reviewed-by: Paolo Bonzini Signed-off-by: Michael S. Tsirkin --- hw/timer/hpet.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'hw/timer') diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 0aee2c1c41..0ec440e7be 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -73,6 +73,7 @@ typedef struct HPETState { uint8_t rtc_irq_level; qemu_irq pit_enabled; uint8_t num_timers; + uint32_t intcap; HPETTimer timer[HPET_MAX_TIMERS]; /* Memory-mapped, software visible registers */ @@ -663,8 +664,8 @@ static void hpet_reset(DeviceState *d) if (s->flags & (1 << HPET_MSI_SUPPORT)) { timer->config |= HPET_TN_FSB_CAP; } - /* advertise availability of ioapic inti2 */ - timer->config |= 0x00000004ULL << 32; + /* advertise availability of ioapic int */ + timer->config |= (uint64_t)s->intcap << 32; timer->period = 0ULL; timer->wrap_flag = 0; } @@ -713,6 +714,9 @@ static void hpet_realize(DeviceState *dev, Error **errp) int i; HPETTimer *timer; + if (!s->intcap) { + error_printf("Hpet's intcap not initialized.\n"); + } if (hpet_cfg.count == UINT8_MAX) { /* first instance */ hpet_cfg.count = 0; @@ -753,6 +757,7 @@ static void hpet_realize(DeviceState *dev, Error **errp) static Property hpet_device_properties[] = { DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS), DEFINE_PROP_BIT("msi", HPETState, flags, HPET_MSI_SUPPORT, false), + DEFINE_PROP_UINT32(HPET_INTCAP, HPETState, intcap, 0), DEFINE_PROP_END_OF_LIST(), }; -- cgit v1.2.1 From 142e0950cfaf023a81112dc3cdfa799d769886a4 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 11 Dec 2013 02:47:16 +0200 Subject: hpet: fix build with CONFIG_HPET off make hpet_find inline so we don't need to build hpet.c to check if hpet is enabled. Fixes link error with CONFIG_HPET off. Cc: qemu-stable@nongnu.org Signed-off-by: Michael S. Tsirkin --- hw/timer/hpet.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'hw/timer') diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 0ec440e7be..bb3bf98745 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -42,7 +42,6 @@ #define HPET_MSI_SUPPORT 0 -#define TYPE_HPET "hpet" #define HPET(obj) OBJECT_CHECK(HPETState, (obj), TYPE_HPET) struct HPETState; @@ -772,11 +771,6 @@ static void hpet_device_class_init(ObjectClass *klass, void *data) dc->props = hpet_device_properties; } -bool hpet_find(void) -{ - return object_resolve_path_type("", TYPE_HPET, NULL); -} - static const TypeInfo hpet_device_info = { .name = TYPE_HPET, .parent = TYPE_SYS_BUS_DEVICE, -- cgit v1.2.1