All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements
@ 2010-06-13 12:15 Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 01/13] hpet: Catch out-of-bounds timer access Jan Kiszka
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Paul Brook, Gleb Natapov, Juan Quintela

As the discussion around how to extend the IRQ framework /wrt
de-coalescing or message passing support still hasn't settled yet, this
series now skips the related changes, just focusing on the HPET. No
further changes compared to v3. Please merge.

Jan Kiszka (13):
  hpet: Catch out-of-bounds timer access
  hpet: Coding style cleanups and some refactorings
  hpet: Silence warning on write to running main counter
  hpet: Move static timer field initialization
  hpet: Convert to qdev
  hpet: Start/stop timer when HPET_TN_ENABLE is modified
  hpet/rtc: Rework RTC IRQ replacement by HPET
  hpet: Drop static state
  hpet: Add support for level-triggered interrupts
  vmstate: Add VMSTATE_STRUCT_VARRAY_UINT8
  hpet: Make number of timers configurable
  hpet: Add MSI support
  monitor/QMP: Drop info hpet / query-hpet

 QMP/vm-info      |    2 +-
 hw/hpet.c        |  580 +++++++++++++++++++++++++++++++++--------------------
 hw/hpet_emul.h   |   46 +----
 hw/hw.h          |   10 +
 hw/mc146818rtc.c |   49 ++----
 hw/mc146818rtc.h |    4 +-
 hw/mips_jazz.c   |    2 +-
 hw/mips_malta.c  |    2 +-
 hw/mips_r4k.c    |    2 +-
 hw/pc.c          |   15 +-
 hw/ppc_prep.c    |    2 +-
 monitor.c        |   22 --
 qemu-monitor.hx  |   21 --
 13 files changed, 415 insertions(+), 342 deletions(-)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 01/13] hpet: Catch out-of-bounds timer access
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 02/13] hpet: Coding style cleanups and some refactorings Jan Kiszka
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

Also prevent out-of-bounds write access to the timers but don't spam the
host console if it triggers.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/hpet.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/hw/hpet.c b/hw/hpet.c
index 8729fb2..1980906 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -294,7 +294,7 @@ static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
     if (index >= 0x100 && index <= 0x3ff) {
         uint8_t timer_id = (addr - 0x100) / 0x20;
         if (timer_id > HPET_NUM_TIMERS - 1) {
-            printf("qemu: timer id out of range\n");
+            DPRINTF("qemu: timer id out of range\n");
             return 0;
         }
         HPETTimer *timer = &s->timer[timer_id];
@@ -383,6 +383,10 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
         DPRINTF("qemu: hpet_ram_writel timer_id = %#x \n", timer_id);
         HPETTimer *timer = &s->timer[timer_id];
 
+        if (timer_id > HPET_NUM_TIMERS - 1) {
+            DPRINTF("qemu: timer id out of range\n");
+            return;
+        }
         switch ((addr - 0x100) % 0x20) {
             case HPET_TN_CFG:
                 DPRINTF("qemu: hpet_ram_writel HPET_TN_CFG\n");
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 02/13] hpet: Coding style cleanups and some refactorings
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 01/13] hpet: Catch out-of-bounds timer access Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 03/13] hpet: Silence warning on write to running main counter Jan Kiszka
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

This moves the private HPET structures into the C module, simplifies
some helper functions and fixes most coding style issues (biggest chunk
was improper switch-case indention). No functional changes.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
---
 hw/hpet.c      |  413 ++++++++++++++++++++++++++++++-------------------------
 hw/hpet_emul.h |   31 +----
 2 files changed, 226 insertions(+), 218 deletions(-)

diff --git a/hw/hpet.c b/hw/hpet.c
index 1980906..2836fb0 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -37,21 +37,47 @@
 #define DPRINTF(...)
 #endif
 
+struct HPETState;
+typedef struct HPETTimer {  /* timers */
+    uint8_t tn;             /*timer number*/
+    QEMUTimer *qemu_timer;
+    struct HPETState *state;
+    /* Memory-mapped, software visible timer registers */
+    uint64_t config;        /* configuration/cap */
+    uint64_t cmp;           /* comparator */
+    uint64_t fsb;           /* FSB route, not supported now */
+    /* Hidden register state */
+    uint64_t period;        /* Last value written to comparator */
+    uint8_t wrap_flag;      /* timer pop will indicate wrap for one-shot 32-bit
+                             * mode. Next pop will be actual timer expiration.
+                             */
+} HPETTimer;
+
+typedef struct HPETState {
+    uint64_t hpet_offset;
+    qemu_irq *irqs;
+    HPETTimer timer[HPET_NUM_TIMERS];
+
+    /* Memory-mapped, software visible registers */
+    uint64_t capability;        /* capabilities */
+    uint64_t config;            /* configuration */
+    uint64_t isr;               /* interrupt status reg */
+    uint64_t hpet_counter;      /* main counter */
+} HPETState;
+
 static HPETState *hpet_statep;
 
 uint32_t hpet_in_legacy_mode(void)
 {
-    if (hpet_statep)
-        return hpet_statep->config & HPET_CFG_LEGACY;
-    else
+    if (!hpet_statep) {
         return 0;
+    }
+    return hpet_statep->config & HPET_CFG_LEGACY;
 }
 
 static uint32_t timer_int_route(struct HPETTimer *timer)
 {
-    uint32_t route;
-    route = (timer->config & HPET_TN_INT_ROUTE_MASK) >> HPET_TN_INT_ROUTE_SHIFT;
-    return route;
+    return (timer->config & HPET_TN_INT_ROUTE_MASK) >> HPET_TN_INT_ROUTE_SHIFT;
 }
 
 static uint32_t hpet_enabled(void)
@@ -108,9 +134,7 @@ static int deactivating_bit(uint64_t old, uint64_t new, uint64_t mask)
 
 static uint64_t hpet_get_ticks(void)
 {
-    uint64_t ticks;
-    ticks = ns_to_ticks(qemu_get_clock(vm_clock) + hpet_statep->hpet_offset);
-    return ticks;
+    return ns_to_ticks(qemu_get_clock(vm_clock) + hpet_statep->hpet_offset);
 }
 
 /*
@@ -121,12 +145,14 @@ static inline uint64_t hpet_calculate_diff(HPETTimer *t, uint64_t current)
 
     if (t->config & HPET_TN_32BIT) {
         uint32_t diff, cmp;
+
         cmp = (uint32_t)t->cmp;
         diff = cmp - (uint32_t)current;
         diff = (int32_t)diff > 0 ? diff : (uint32_t)0;
         return (uint64_t)diff;
     } else {
         uint64_t diff, cmp;
+
         cmp = t->cmp;
         diff = cmp - current;
         diff = (int64_t)diff > 0 ? diff : (uint64_t)0;
@@ -136,7 +162,6 @@ static inline uint64_t hpet_calculate_diff(HPETTimer *t, uint64_t current)
 
 static void update_irq(struct HPETTimer *timer)
 {
-    qemu_irq irq;
     int route;
 
     if (timer->tn <= 1 && hpet_in_legacy_mode()) {
@@ -144,22 +169,20 @@ static void update_irq(struct HPETTimer *timer)
          * timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC,
          * timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC.
          */
-        if (timer->tn == 0) {
-            irq=timer->state->irqs[0];
-        } else
-            irq=timer->state->irqs[8];
+        route = (timer->tn == 0) ? 0 : 8;
     } else {
-        route=timer_int_route(timer);
-        irq=timer->state->irqs[route];
+        route = timer_int_route(timer);
     }
-    if (timer_enabled(timer) && hpet_enabled()) {
-        qemu_irq_pulse(irq);
+    if (!timer_enabled(timer) || !hpet_enabled()) {
+        return;
     }
+    qemu_irq_pulse(timer->state->irqs[route]);
 }
 
 static void hpet_pre_save(void *opaque)
 {
     HPETState *s = opaque;
+
     /* save current counter value */
     s->hpet_counter = hpet_get_ticks();
 }
@@ -212,7 +235,7 @@ static const VMStateDescription vmstate_hpet = {
  */
 static void hpet_timer(void *opaque)
 {
-    HPETTimer *t = (HPETTimer*)opaque;
+    HPETTimer *t = opaque;
     uint64_t diff;
 
     uint64_t period = t->period;
@@ -220,20 +243,22 @@ static void hpet_timer(void *opaque)
 
     if (timer_is_periodic(t) && period != 0) {
         if (t->config & HPET_TN_32BIT) {
-            while (hpet_time_after(cur_tick, t->cmp))
+            while (hpet_time_after(cur_tick, t->cmp)) {
                 t->cmp = (uint32_t)(t->cmp + t->period);
-        } else
-            while (hpet_time_after64(cur_tick, t->cmp))
+            }
+        } else {
+            while (hpet_time_after64(cur_tick, t->cmp)) {
                 t->cmp += period;
-
+            }
+        }
         diff = hpet_calculate_diff(t, cur_tick);
-        qemu_mod_timer(t->qemu_timer, qemu_get_clock(vm_clock)
-                       + (int64_t)ticks_to_ns(diff));
+        qemu_mod_timer(t->qemu_timer,
+                       qemu_get_clock(vm_clock) + (int64_t)ticks_to_ns(diff));
     } else if (t->config & HPET_TN_32BIT && !timer_is_periodic(t)) {
         if (t->wrap_flag) {
             diff = hpet_calculate_diff(t, cur_tick);
-            qemu_mod_timer(t->qemu_timer, qemu_get_clock(vm_clock)
-                           + (int64_t)ticks_to_ns(diff));
+            qemu_mod_timer(t->qemu_timer, qemu_get_clock(vm_clock) +
+                           (int64_t)ticks_to_ns(diff));
             t->wrap_flag = 0;
         }
     }
@@ -260,8 +285,8 @@ static void hpet_set_timer(HPETTimer *t)
             t->wrap_flag = 1;
         }
     }
-    qemu_mod_timer(t->qemu_timer, qemu_get_clock(vm_clock)
-                   + (int64_t)ticks_to_ns(diff));
+    qemu_mod_timer(t->qemu_timer,
+                   qemu_get_clock(vm_clock) + (int64_t)ticks_to_ns(diff));
 }
 
 static void hpet_del_timer(HPETTimer *t)
@@ -285,7 +310,7 @@ static uint32_t hpet_ram_readw(void *opaque, target_phys_addr_t addr)
 
 static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
 {
-    HPETState *s = (HPETState *)opaque;
+    HPETState *s = opaque;
     uint64_t cur_tick, index;
 
     DPRINTF("qemu: Enter hpet_ram_readl at %" PRIx64 "\n", addr);
@@ -293,57 +318,60 @@ static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
     /*address range of all TN regs*/
     if (index >= 0x100 && index <= 0x3ff) {
         uint8_t timer_id = (addr - 0x100) / 0x20;
+        HPETTimer *timer = &s->timer[timer_id];
+
         if (timer_id > HPET_NUM_TIMERS - 1) {
             DPRINTF("qemu: timer id out of range\n");
             return 0;
         }
-        HPETTimer *timer = &s->timer[timer_id];
 
         switch ((addr - 0x100) % 0x20) {
-            case HPET_TN_CFG:
-                return timer->config;
-            case HPET_TN_CFG + 4: // Interrupt capabilities
-                return timer->config >> 32;
-            case HPET_TN_CMP: // comparator register
-                return timer->cmp;
-            case HPET_TN_CMP + 4:
-                return timer->cmp >> 32;
-            case HPET_TN_ROUTE:
-                return timer->fsb >> 32;
-            default:
-                DPRINTF("qemu: invalid hpet_ram_readl\n");
-                break;
+        case HPET_TN_CFG:
+            return timer->config;
+        case HPET_TN_CFG + 4: // Interrupt capabilities
+            return timer->config >> 32;
+        case HPET_TN_CMP: // comparator register
+            return timer->cmp;
+        case HPET_TN_CMP + 4:
+            return timer->cmp >> 32;
+        case HPET_TN_ROUTE:
+            return timer->fsb >> 32;
+        default:
+            DPRINTF("qemu: invalid hpet_ram_readl\n");
+            break;
         }
     } else {
         switch (index) {
-            case HPET_ID:
-                return s->capability;
-            case HPET_PERIOD:
-                return s->capability >> 32;
-            case HPET_CFG:
-                return s->config;
-            case HPET_CFG + 4:
-                DPRINTF("qemu: invalid HPET_CFG + 4 hpet_ram_readl \n");
-                return 0;
-            case HPET_COUNTER:
-                if (hpet_enabled())
-                    cur_tick = hpet_get_ticks();
-                else
-                    cur_tick = s->hpet_counter;
-                DPRINTF("qemu: reading counter  = %" PRIx64 "\n", cur_tick);
-                return cur_tick;
-            case HPET_COUNTER + 4:
-                if (hpet_enabled())
-                    cur_tick = hpet_get_ticks();
-                else
-                    cur_tick = s->hpet_counter;
-                DPRINTF("qemu: reading counter + 4  = %" PRIx64 "\n", cur_tick);
-                return cur_tick >> 32;
-            case HPET_STATUS:
-                return s->isr;
-            default:
-                DPRINTF("qemu: invalid hpet_ram_readl\n");
-                break;
+        case HPET_ID:
+            return s->capability;
+        case HPET_PERIOD:
+            return s->capability >> 32;
+        case HPET_CFG:
+            return s->config;
+        case HPET_CFG + 4:
+            DPRINTF("qemu: invalid HPET_CFG + 4 hpet_ram_readl \n");
+            return 0;
+        case HPET_COUNTER:
+            if (hpet_enabled()) {
+                cur_tick = hpet_get_ticks();
+            } else {
+                cur_tick = s->hpet_counter;
+            }
+            DPRINTF("qemu: reading counter  = %" PRIx64 "\n", cur_tick);
+            return cur_tick;
+        case HPET_COUNTER + 4:
+            if (hpet_enabled()) {
+                cur_tick = hpet_get_ticks();
+            } else {
+                cur_tick = s->hpet_counter;
+            }
+            DPRINTF("qemu: reading counter + 4  = %" PRIx64 "\n", cur_tick);
+            return cur_tick >> 32;
+        case HPET_STATUS:
+            return s->isr;
+        default:
+            DPRINTF("qemu: invalid hpet_ram_readl\n");
+            break;
         }
     }
     return 0;
@@ -369,7 +397,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
                             uint32_t value)
 {
     int i;
-    HPETState *s = (HPETState *)opaque;
+    HPETState *s = opaque;
     uint64_t old_val, new_val, val, index;
 
     DPRINTF("qemu: Enter hpet_ram_writel at %" PRIx64 " = %#x\n", addr, value);
@@ -380,133 +408,137 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
     /*address range of all TN regs*/
     if (index >= 0x100 && index <= 0x3ff) {
         uint8_t timer_id = (addr - 0x100) / 0x20;
-        DPRINTF("qemu: hpet_ram_writel timer_id = %#x \n", timer_id);
         HPETTimer *timer = &s->timer[timer_id];
 
+        DPRINTF("qemu: hpet_ram_writel timer_id = %#x \n", timer_id);
         if (timer_id > HPET_NUM_TIMERS - 1) {
             DPRINTF("qemu: timer id out of range\n");
             return;
         }
         switch ((addr - 0x100) % 0x20) {
-            case HPET_TN_CFG:
-                DPRINTF("qemu: hpet_ram_writel HPET_TN_CFG\n");
-                val = hpet_fixup_reg(new_val, old_val, HPET_TN_CFG_WRITE_MASK);
-                timer->config = (timer->config & 0xffffffff00000000ULL) | val;
-                if (new_val & HPET_TN_32BIT) {
-                    timer->cmp = (uint32_t)timer->cmp;
-                    timer->period = (uint32_t)timer->period;
-                }
-                if (new_val & HPET_TIMER_TYPE_LEVEL) {
-                    printf("qemu: level-triggered hpet not supported\n");
-                    exit (-1);
-                }
-
-                break;
-            case HPET_TN_CFG + 4: // Interrupt capabilities
-                DPRINTF("qemu: invalid HPET_TN_CFG+4 write\n");
-                break;
-            case HPET_TN_CMP: // comparator register
-                DPRINTF("qemu: hpet_ram_writel HPET_TN_CMP \n");
-                if (timer->config & HPET_TN_32BIT)
-                    new_val = (uint32_t)new_val;
-                if (!timer_is_periodic(timer) ||
-                           (timer->config & HPET_TN_SETVAL))
-                    timer->cmp = (timer->cmp & 0xffffffff00000000ULL)
-                                  | new_val;
-                if (timer_is_periodic(timer)) {
-                    /*
-                     * FIXME: Clamp period to reasonable min value?
-                     * Clamp period to reasonable max value
-                     */
-                    new_val &= (timer->config & HPET_TN_32BIT ? ~0u : ~0ull) >> 1;
-                    timer->period = (timer->period & 0xffffffff00000000ULL)
-                                     | new_val;
+        case HPET_TN_CFG:
+            DPRINTF("qemu: hpet_ram_writel HPET_TN_CFG\n");
+            val = hpet_fixup_reg(new_val, old_val, HPET_TN_CFG_WRITE_MASK);
+            timer->config = (timer->config & 0xffffffff00000000ULL) | val;
+            if (new_val & HPET_TN_32BIT) {
+                timer->cmp = (uint32_t)timer->cmp;
+                timer->period = (uint32_t)timer->period;
+            }
+            if (new_val & HPET_TN_TYPE_LEVEL) {
+                printf("qemu: level-triggered hpet not supported\n");
+                exit (-1);
+            }
+            break;
+        case HPET_TN_CFG + 4: // Interrupt capabilities
+            DPRINTF("qemu: invalid HPET_TN_CFG+4 write\n");
+            break;
+        case HPET_TN_CMP: // comparator register
+            DPRINTF("qemu: hpet_ram_writel HPET_TN_CMP \n");
+            if (timer->config & HPET_TN_32BIT) {
+                new_val = (uint32_t)new_val;
+            }
+            if (!timer_is_periodic(timer)
+                || (timer->config & HPET_TN_SETVAL)) {
+                timer->cmp = (timer->cmp & 0xffffffff00000000ULL) | new_val;
+            }
+            if (timer_is_periodic(timer)) {
+                /*
+                 * FIXME: Clamp period to reasonable min value?
+                 * Clamp period to reasonable max value
+                 */
+                new_val &= (timer->config & HPET_TN_32BIT ? ~0u : ~0ull) >> 1;
+                timer->period =
+                    (timer->period & 0xffffffff00000000ULL) | new_val;
+            }
+            timer->config &= ~HPET_TN_SETVAL;
+            if (hpet_enabled()) {
+                hpet_set_timer(timer);
+            }
+            break;
+        case HPET_TN_CMP + 4: // comparator register high order
+            DPRINTF("qemu: hpet_ram_writel HPET_TN_CMP + 4\n");
+            if (!timer_is_periodic(timer)
+                || (timer->config & HPET_TN_SETVAL)) {
+                timer->cmp = (timer->cmp & 0xffffffffULL) | new_val << 32;
+            } else {
+                /*
+                 * FIXME: Clamp period to reasonable min value?
+                 * Clamp period to reasonable max value
+                 */
+                new_val &= (timer->config & HPET_TN_32BIT ? ~0u : ~0ull) >> 1;
+                timer->period =
+                    (timer->period & 0xffffffffULL) | new_val << 32;
                 }
                 timer->config &= ~HPET_TN_SETVAL;
-                if (hpet_enabled())
+                if (hpet_enabled()) {
                     hpet_set_timer(timer);
-                break;
-            case HPET_TN_CMP + 4: // comparator register high order
-                DPRINTF("qemu: hpet_ram_writel HPET_TN_CMP + 4\n");
-                if (!timer_is_periodic(timer) ||
-                           (timer->config & HPET_TN_SETVAL))
-                    timer->cmp = (timer->cmp & 0xffffffffULL)
-                                  | new_val << 32;
-                else {
-                    /*
-                     * FIXME: Clamp period to reasonable min value?
-                     * Clamp period to reasonable max value
-                     */
-                    new_val &= (timer->config
-                                & HPET_TN_32BIT ? ~0u : ~0ull) >> 1;
-                    timer->period = (timer->period & 0xffffffffULL)
-                                     | new_val << 32;
                 }
-                timer->config &= ~HPET_TN_SETVAL;
-                if (hpet_enabled())
-                    hpet_set_timer(timer);
-                break;
-            case HPET_TN_ROUTE + 4:
-                DPRINTF("qemu: hpet_ram_writel HPET_TN_ROUTE + 4\n");
-                break;
-            default:
-                DPRINTF("qemu: invalid hpet_ram_writel\n");
                 break;
+        case HPET_TN_ROUTE + 4:
+            DPRINTF("qemu: hpet_ram_writel HPET_TN_ROUTE + 4\n");
+            break;
+        default:
+            DPRINTF("qemu: invalid hpet_ram_writel\n");
+            break;
         }
         return;
     } else {
         switch (index) {
-            case HPET_ID:
-                return;
-            case HPET_CFG:
-                val = hpet_fixup_reg(new_val, old_val, HPET_CFG_WRITE_MASK);
-                s->config = (s->config & 0xffffffff00000000ULL) | val;
-                if (activating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
-                    /* Enable main counter and interrupt generation. */
-                    s->hpet_offset = ticks_to_ns(s->hpet_counter)
-                                     - qemu_get_clock(vm_clock);
-                    for (i = 0; i < HPET_NUM_TIMERS; i++)
-                        if ((&s->timer[i])->cmp != ~0ULL)
-                            hpet_set_timer(&s->timer[i]);
-                }
-                else if (deactivating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
-                    /* Halt main counter and disable interrupt generation. */
-                    s->hpet_counter = hpet_get_ticks();
-                    for (i = 0; i < HPET_NUM_TIMERS; i++)
-                        hpet_del_timer(&s->timer[i]);
+        case HPET_ID:
+            return;
+        case HPET_CFG:
+            val = hpet_fixup_reg(new_val, old_val, HPET_CFG_WRITE_MASK);
+            s->config = (s->config & 0xffffffff00000000ULL) | val;
+            if (activating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
+                /* Enable main counter and interrupt generation. */
+                s->hpet_offset =
+                    ticks_to_ns(s->hpet_counter) - qemu_get_clock(vm_clock);
+                for (i = 0; i < HPET_NUM_TIMERS; i++) {
+                    if ((&s->timer[i])->cmp != ~0ULL) {
+                        hpet_set_timer(&s->timer[i]);
+                    }
                 }
-                /* i8254 and RTC are disabled when HPET is in legacy mode */
-                if (activating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
-                    hpet_pit_disable();
-                } else if (deactivating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
-                    hpet_pit_enable();
+            } else if (deactivating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
+                /* Halt main counter and disable interrupt generation. */
+                s->hpet_counter = hpet_get_ticks();
+                for (i = 0; i < HPET_NUM_TIMERS; i++) {
+                    hpet_del_timer(&s->timer[i]);
                 }
-                break;
-            case HPET_CFG + 4:
-                DPRINTF("qemu: invalid HPET_CFG+4 write \n");
-                break;
-            case HPET_STATUS:
-                /* FIXME: need to handle level-triggered interrupts */
-                break;
-            case HPET_COUNTER:
-               if (hpet_enabled())
-                   printf("qemu: Writing counter while HPET enabled!\n");
-               s->hpet_counter = (s->hpet_counter & 0xffffffff00000000ULL)
-                                  | value;
-               DPRINTF("qemu: HPET counter written. ctr = %#x -> %" PRIx64 "\n",
-                        value, s->hpet_counter);
-               break;
-            case HPET_COUNTER + 4:
-               if (hpet_enabled())
-                   printf("qemu: Writing counter while HPET enabled!\n");
-               s->hpet_counter = (s->hpet_counter & 0xffffffffULL)
-                                  | (((uint64_t)value) << 32);
-               DPRINTF("qemu: HPET counter + 4 written. ctr = %#x -> %" PRIx64 "\n",
-                        value, s->hpet_counter);
-               break;
-            default:
-               DPRINTF("qemu: invalid hpet_ram_writel\n");
-               break;
+            }
+            /* i8254 and RTC are disabled when HPET is in legacy mode */
+            if (activating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
+                hpet_pit_disable();
+            } else if (deactivating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
+                hpet_pit_enable();
+            }
+            break;
+        case HPET_CFG + 4:
+            DPRINTF("qemu: invalid HPET_CFG+4 write \n");
+            break;
+        case HPET_STATUS:
+            /* FIXME: need to handle level-triggered interrupts */
+            break;
+        case HPET_COUNTER:
+            if (hpet_enabled()) {
+                printf("qemu: Writing counter while HPET enabled!\n");
+            }
+            s->hpet_counter =
+                (s->hpet_counter & 0xffffffff00000000ULL) | value;
+            DPRINTF("qemu: HPET counter written. ctr = %#x -> %" PRIx64 "\n",
+                    value, s->hpet_counter);
+            break;
+        case HPET_COUNTER + 4:
+            if (hpet_enabled()) {
+                printf("qemu: Writing counter while HPET enabled!\n");
+            }
+            s->hpet_counter =
+                (s->hpet_counter & 0xffffffffULL) | (((uint64_t)value) << 32);
+            DPRINTF("qemu: HPET counter + 4 written. ctr = %#x -> %" PRIx64 "\n",
+                    value, s->hpet_counter);
+            break;
+        default:
+            DPRINTF("qemu: invalid hpet_ram_writel\n");
+            break;
         }
     }
 }
@@ -533,13 +565,15 @@ static CPUWriteMemoryFunc * const hpet_ram_write[] = {
     hpet_ram_writel,
 };
 
-static void hpet_reset(void *opaque) {
+static void hpet_reset(void *opaque)
+{
     HPETState *s = opaque;
     int i;
     static int count = 0;
 
-    for (i=0; i<HPET_NUM_TIMERS; i++) {
+    for (i = 0; i < HPET_NUM_TIMERS; i++) {
         HPETTimer *timer = &s->timer[i];
+
         hpet_del_timer(timer);
         timer->tn = i;
         timer->cmp = ~0ULL;
@@ -557,19 +591,22 @@ static void hpet_reset(void *opaque) {
     s->capability = 0x8086a201ULL;
     s->capability |= ((HPET_CLK_PERIOD) << 32);
     s->config = 0ULL;
-    if (count > 0)
+    if (count > 0) {
         /* we don't enable pit when hpet_reset is first called (by hpet_init)
          * because hpet is taking over for pit here. On subsequent invocations,
          * hpet_reset is called due to system reset. At this point control must
          * be returned to pit until SW reenables hpet.
          */
         hpet_pit_enable();
+    }
     count = 1;
 }
 
 
-void hpet_init(qemu_irq *irq) {
+void hpet_init(qemu_irq *irq)
+{
     int i, iomemtype;
+    HPETTimer *timer;
     HPETState *s;
 
     DPRINTF ("hpet_init\n");
@@ -577,8 +614,8 @@ void hpet_init(qemu_irq *irq) {
     s = qemu_mallocz(sizeof(HPETState));
     hpet_statep = s;
     s->irqs = irq;
-    for (i=0; i<HPET_NUM_TIMERS; i++) {
-        HPETTimer *timer = &s->timer[i];
+    for (i = 0; i < HPET_NUM_TIMERS; i++) {
+        timer = &s->timer[i];
         timer->qemu_timer = qemu_new_timer(vm_clock, hpet_timer, timer);
     }
     vmstate_register(-1, &vmstate_hpet, s);
diff --git a/hw/hpet_emul.h b/hw/hpet_emul.h
index cfd95b4..2f5f8ba 100644
--- a/hw/hpet_emul.h
+++ b/hw/hpet_emul.h
@@ -18,7 +18,6 @@
 
 #define FS_PER_NS 1000000
 #define HPET_NUM_TIMERS 3
-#define HPET_TIMER_TYPE_LEVEL 0x002
 
 #define HPET_CFG_ENABLE 0x001
 #define HPET_CFG_LEGACY 0x002
@@ -33,7 +32,7 @@
 #define HPET_TN_ROUTE   0x010
 #define HPET_CFG_WRITE_MASK  0x3
 
-
+#define HPET_TN_TYPE_LEVEL       0x002
 #define HPET_TN_ENABLE           0x004
 #define HPET_TN_PERIODIC         0x008
 #define HPET_TN_PERIODIC_CAP     0x010
@@ -46,34 +45,6 @@
 #define HPET_TN_INT_ROUTE_CAP_SHIFT 32
 #define HPET_TN_CFG_BITS_READONLY_OR_RESERVED 0xffff80b1U
 
-struct HPETState;
-typedef struct HPETTimer {  /* timers */
-    uint8_t tn;             /*timer number*/
-    QEMUTimer *qemu_timer;
-    struct HPETState *state;
-    /* Memory-mapped, software visible timer registers */
-    uint64_t config;        /* configuration/cap */
-    uint64_t cmp;           /* comparator */
-    uint64_t fsb;           /* FSB route, not supported now */
-    /* Hidden register state */
-    uint64_t period;        /* Last value written to comparator */
-    uint8_t wrap_flag;      /* timer pop will indicate wrap for one-shot 32-bit
-                             * mode. Next pop will be actual timer expiration.
-                             */
-} HPETTimer;
-
-typedef struct HPETState {
-    uint64_t hpet_offset;
-    qemu_irq *irqs;
-    HPETTimer timer[HPET_NUM_TIMERS];
-
-    /* Memory-mapped, software visible registers */
-    uint64_t capability;        /* capabilities */
-    uint64_t config;            /* configuration */
-    uint64_t isr;               /* interrupt status reg */
-    uint64_t hpet_counter;      /* main counter */
-} HPETState;
-
 #if defined TARGET_I386
 extern uint32_t hpet_in_legacy_mode(void);
 extern void hpet_init(qemu_irq *irq);
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 03/13] hpet: Silence warning on write to running main counter
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 01/13] hpet: Catch out-of-bounds timer access Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 02/13] hpet: Coding style cleanups and some refactorings Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 04/13] hpet: Move static timer field initialization Jan Kiszka
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

Setting the main counter while the HPET is enabled may not be a good
idea of the guest, but it is supported and should, thus, not spam the
host console with warnings.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/hpet.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/hpet.c b/hw/hpet.c
index 2836fb0..bcb160b 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -520,7 +520,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
             break;
         case HPET_COUNTER:
             if (hpet_enabled()) {
-                printf("qemu: Writing counter while HPET enabled!\n");
+                DPRINTF("qemu: Writing counter while HPET enabled!\n");
             }
             s->hpet_counter =
                 (s->hpet_counter & 0xffffffff00000000ULL) | value;
@@ -529,7 +529,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
             break;
         case HPET_COUNTER + 4:
             if (hpet_enabled()) {
-                printf("qemu: Writing counter while HPET enabled!\n");
+                DPRINTF("qemu: Writing counter while HPET enabled!\n");
             }
             s->hpet_counter =
                 (s->hpet_counter & 0xffffffffULL) | (((uint64_t)value) << 32);
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 04/13] hpet: Move static timer field initialization
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
                   ` (2 preceding siblings ...)
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 03/13] hpet: Silence warning on write to running main counter Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 05/13] hpet: Convert to qdev Jan Kiszka
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

Properly initialize HPETTimer::tn and HPETTimer::state once during
hpet_init instead of (re-)writing them on every reset.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/hpet.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/hpet.c b/hw/hpet.c
index bcb160b..fd7a1fd 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -575,12 +575,10 @@ static void hpet_reset(void *opaque)
         HPETTimer *timer = &s->timer[i];
 
         hpet_del_timer(timer);
-        timer->tn = i;
         timer->cmp = ~0ULL;
         timer->config =  HPET_TN_PERIODIC_CAP | HPET_TN_SIZE_CAP;
         /* advertise availability of ioapic inti2 */
         timer->config |=  0x00000004ULL << 32;
-        timer->state = s;
         timer->period = 0ULL;
         timer->wrap_flag = 0;
     }
@@ -617,6 +615,8 @@ void hpet_init(qemu_irq *irq)
     for (i = 0; i < HPET_NUM_TIMERS; i++) {
         timer = &s->timer[i];
         timer->qemu_timer = qemu_new_timer(vm_clock, hpet_timer, timer);
+        timer->tn = i;
+        timer->state = s;
     }
     vmstate_register(-1, &vmstate_hpet, s);
     qemu_register_reset(hpet_reset, s);
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 05/13] hpet: Convert to qdev
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
                   ` (3 preceding siblings ...)
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 04/13] hpet: Move static timer field initialization Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 06/13] hpet: Start/stop timer when HPET_TN_ENABLE is modified Jan Kiszka
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

Register the HPET as a sysbus device and create it that way. As it can
route its IRQs to any ISA IRQ, we need to connect it to all 24 of them.
Once converted to qdev, we can move reset handler and vmstate
registration into its hands as well.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/hpet.c      |   43 ++++++++++++++++++++++++++++++-------------
 hw/hpet_emul.h |    3 ++-
 hw/pc.c        |    7 ++++++-
 3 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/hw/hpet.c b/hw/hpet.c
index fd7a1fd..6974935 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -29,6 +29,7 @@
 #include "console.h"
 #include "qemu-timer.h"
 #include "hpet_emul.h"
+#include "sysbus.h"
 
 //#define HPET_DEBUG
 #ifdef HPET_DEBUG
@@ -54,8 +55,9 @@ typedef struct HPETTimer {  /* timers */
 } HPETTimer;
 
 typedef struct HPETState {
+    SysBusDevice busdev;
     uint64_t hpet_offset;
-    qemu_irq *irqs;
+    qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
     HPETTimer timer[HPET_NUM_TIMERS];
 
     /* Memory-mapped, software visible registers */
@@ -565,9 +567,9 @@ static CPUWriteMemoryFunc * const hpet_ram_write[] = {
     hpet_ram_writel,
 };
 
-static void hpet_reset(void *opaque)
+static void hpet_reset(DeviceState *d)
 {
-    HPETState *s = opaque;
+    HPETState *s = FROM_SYSBUS(HPETState, sysbus_from_qdev(d));
     int i;
     static int count = 0;
 
@@ -600,28 +602,43 @@ static void hpet_reset(void *opaque)
     count = 1;
 }
 
-
-void hpet_init(qemu_irq *irq)
+static int hpet_init(SysBusDevice *dev)
 {
+    HPETState *s = FROM_SYSBUS(HPETState, dev);
     int i, iomemtype;
     HPETTimer *timer;
-    HPETState *s;
-
-    DPRINTF ("hpet_init\n");
 
-    s = qemu_mallocz(sizeof(HPETState));
+    assert(!hpet_statep);
     hpet_statep = s;
-    s->irqs = irq;
+    for (i = 0; i < HPET_NUM_IRQ_ROUTES; i++) {
+        sysbus_init_irq(dev, &s->irqs[i]);
+    }
     for (i = 0; i < HPET_NUM_TIMERS; i++) {
         timer = &s->timer[i];
         timer->qemu_timer = qemu_new_timer(vm_clock, hpet_timer, timer);
         timer->tn = i;
         timer->state = s;
     }
-    vmstate_register(-1, &vmstate_hpet, s);
-    qemu_register_reset(hpet_reset, s);
+
     /* HPET Area */
     iomemtype = cpu_register_io_memory(hpet_ram_read,
                                        hpet_ram_write, s);
-    cpu_register_physical_memory(HPET_BASE, 0x400, iomemtype);
+    sysbus_init_mmio(dev, 0x400, iomemtype);
+    return 0;
 }
+
+static SysBusDeviceInfo hpet_device_info = {
+    .qdev.name    = "hpet",
+    .qdev.size    = sizeof(HPETState),
+    .qdev.no_user = 1,
+    .qdev.vmsd    = &vmstate_hpet,
+    .qdev.reset   = hpet_reset,
+    .init         = hpet_init,
+};
+
+static void hpet_register_device(void)
+{
+    sysbus_register_withprop(&hpet_device_info);
+}
+
+device_init(hpet_register_device)
diff --git a/hw/hpet_emul.h b/hw/hpet_emul.h
index 2f5f8ba..785f850 100644
--- a/hw/hpet_emul.h
+++ b/hw/hpet_emul.h
@@ -19,6 +19,8 @@
 #define FS_PER_NS 1000000
 #define HPET_NUM_TIMERS 3
 
+#define HPET_NUM_IRQ_ROUTES     32
+
 #define HPET_CFG_ENABLE 0x001
 #define HPET_CFG_LEGACY 0x002
 
@@ -47,7 +49,6 @@
 
 #if defined TARGET_I386
 extern uint32_t hpet_in_legacy_mode(void);
-extern void hpet_init(qemu_irq *irq);
 #endif
 
 #endif
diff --git a/hw/pc.c b/hw/pc.c
index 9b85c42..ae31e2e 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -35,6 +35,7 @@
 #include "elf.h"
 #include "multiboot.h"
 #include "mc146818rtc.h"
+#include "sysbus.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -957,7 +958,11 @@ void pc_basic_device_init(qemu_irq *isa_irq,
     pit = pit_init(0x40, isa_reserve_irq(0));
     pcspk_init(pit);
     if (!no_hpet) {
-        hpet_init(isa_irq);
+        DeviceState *hpet = sysbus_create_simple("hpet", HPET_BASE, NULL);
+
+        for (i = 0; i < 24; i++) {
+            sysbus_connect_irq(sysbus_from_qdev(hpet), i, isa_irq[i]);
+        }
     }
 
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 06/13] hpet: Start/stop timer when HPET_TN_ENABLE is modified
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
                   ` (4 preceding siblings ...)
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 05/13] hpet: Convert to qdev Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 07/13] hpet/rtc: Rework RTC IRQ replacement by HPET Jan Kiszka
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

We have to update the qemu timer when the per-timer enable bit is
toggled, just like for HPET_CFG_ENABLE changes.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/hpet.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/hw/hpet.c b/hw/hpet.c
index 6974935..041dd84 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -430,6 +430,11 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
                 printf("qemu: level-triggered hpet not supported\n");
                 exit (-1);
             }
+            if (activating_bit(old_val, new_val, HPET_TN_ENABLE)) {
+                hpet_set_timer(timer);
+            } else if (deactivating_bit(old_val, new_val, HPET_TN_ENABLE)) {
+                hpet_del_timer(timer);
+            }
             break;
         case HPET_TN_CFG + 4: // Interrupt capabilities
             DPRINTF("qemu: invalid HPET_TN_CFG+4 write\n");
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 07/13] hpet/rtc: Rework RTC IRQ replacement by HPET
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
                   ` (5 preceding siblings ...)
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 06/13] hpet: Start/stop timer when HPET_TN_ENABLE is modified Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 08/13] hpet: Drop static state Jan Kiszka
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

Allow the intercept the RTC IRQ for the HPET legacy mode. Then push
routing to IRQ8 completely into the HPET. This allows to turn
hpet_in_legacy_mode() into a private function. Furthermore, this stops
the RTC from clearing IRQ8 even if the HPET is in control.

This patch comes with a side effect: The RTC timers will no longer be
stoppend when there is no IRQ consumer, possibly causing a minor
performance degration. But as the guest may want to redirect the RTC to
the SCI in that mode, it should normally disable unused IRQ source
anyway.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/hpet.c        |   28 +++++++++++++++++++++-------
 hw/hpet_emul.h   |    4 ----
 hw/mc146818rtc.c |   49 +++++++++++++++----------------------------------
 hw/mc146818rtc.h |    4 +++-
 hw/mips_jazz.c   |    2 +-
 hw/mips_malta.c  |    2 +-
 hw/mips_r4k.c    |    2 +-
 hw/pc.c          |   14 ++++++++------
 hw/ppc_prep.c    |    2 +-
 9 files changed, 51 insertions(+), 56 deletions(-)

diff --git a/hw/hpet.c b/hw/hpet.c
index 041dd84..edfe02e 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -30,6 +30,7 @@
 #include "qemu-timer.h"
 #include "hpet_emul.h"
 #include "sysbus.h"
+#include "mc146818rtc.h"
 
 //#define HPET_DEBUG
 #ifdef HPET_DEBUG
@@ -58,6 +59,7 @@ typedef struct HPETState {
     SysBusDevice busdev;
     uint64_t hpet_offset;
     qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
+    uint8_t rtc_irq_level;
     HPETTimer timer[HPET_NUM_TIMERS];
 
     /* Memory-mapped, software visible registers */
@@ -69,12 +71,9 @@ typedef struct HPETState {
 
 static HPETState *hpet_statep;
 
-uint32_t hpet_in_legacy_mode(void)
+static uint32_t hpet_in_legacy_mode(HPETState *s)
 {
-    if (!hpet_statep) {
-        return 0;
-    }
-    return hpet_statep->config & HPET_CFG_LEGACY;
+    return s->config & HPET_CFG_LEGACY;
 }
 
 static uint32_t timer_int_route(struct HPETTimer *timer)
@@ -166,12 +165,12 @@ static void update_irq(struct HPETTimer *timer)
 {
     int route;
 
-    if (timer->tn <= 1 && hpet_in_legacy_mode()) {
+    if (timer->tn <= 1 && hpet_in_legacy_mode(timer->state)) {
         /* if LegacyReplacementRoute bit is set, HPET specification requires
          * timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC,
          * timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC.
          */
-        route = (timer->tn == 0) ? 0 : 8;
+        route = (timer->tn == 0) ? 0 : RTC_ISA_IRQ;
     } else {
         route = timer_int_route(timer);
     }
@@ -515,8 +514,10 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
             /* i8254 and RTC are disabled when HPET is in legacy mode */
             if (activating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
                 hpet_pit_disable();
+                qemu_irq_lower(s->irqs[RTC_ISA_IRQ]);
             } else if (deactivating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
                 hpet_pit_enable();
+                qemu_set_irq(s->irqs[RTC_ISA_IRQ], s->rtc_irq_level);
             }
             break;
         case HPET_CFG + 4:
@@ -607,6 +608,16 @@ static void hpet_reset(DeviceState *d)
     count = 1;
 }
 
+static void hpet_handle_rtc_irq(void *opaque, int n, int level)
+{
+    HPETState *s = FROM_SYSBUS(HPETState, opaque);
+
+    s->rtc_irq_level = level;
+    if (!hpet_in_legacy_mode(s)) {
+        qemu_set_irq(s->irqs[RTC_ISA_IRQ], level);
+    }
+}
+
 static int hpet_init(SysBusDevice *dev)
 {
     HPETState *s = FROM_SYSBUS(HPETState, dev);
@@ -625,6 +636,9 @@ static int hpet_init(SysBusDevice *dev)
         timer->state = s;
     }
 
+    isa_reserve_irq(RTC_ISA_IRQ);
+    qdev_init_gpio_in(&dev->qdev, hpet_handle_rtc_irq, 1);
+
     /* HPET Area */
     iomemtype = cpu_register_io_memory(hpet_ram_read,
                                        hpet_ram_write, s);
diff --git a/hw/hpet_emul.h b/hw/hpet_emul.h
index 785f850..9c268cc 100644
--- a/hw/hpet_emul.h
+++ b/hw/hpet_emul.h
@@ -47,8 +47,4 @@
 #define HPET_TN_INT_ROUTE_CAP_SHIFT 32
 #define HPET_TN_CFG_BITS_READONLY_OR_RESERVED 0xffff80b1U
 
-#if defined TARGET_I386
-extern uint32_t hpet_in_legacy_mode(void);
-#endif
-
 #endif
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index c3e6a70..c3459bf 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -27,7 +27,6 @@
 #include "pc.h"
 #include "apic.h"
 #include "isa.h"
-#include "hpet_emul.h"
 #include "mc146818rtc.h"
 
 //#define DEBUG_CMOS
@@ -101,19 +100,6 @@ typedef struct RTCState {
     QEMUTimer *second_timer2;
 } RTCState;
 
-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
-    if (!hpet_in_legacy_mode())
-#endif
-        qemu_irq_raise(irq);
-}
-
 static void rtc_set_time(RTCState *s);
 static void rtc_copy_date(RTCState *s);
 
@@ -139,7 +125,7 @@ static void rtc_coalesced_timer(void *opaque)
         apic_reset_irq_delivered();
         s->cmos_data[RTC_REG_C] |= 0xc0;
         DPRINTF_C("cmos: injecting from timer\n");
-        rtc_irq_raise(s->irq);
+        qemu_irq_raise(s->irq);
         if (apic_get_irq_delivered()) {
             s->irq_coalesced--;
             DPRINTF_C("cmos: coalesced irqs decreased to %d\n",
@@ -155,19 +141,10 @@ 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_PIE)
             || ((s->cmos_data[RTC_REG_B] & REG_B_SQWE) && s->sqw_irq))) {
         if (period_code <= 2)
             period_code += 7;
@@ -206,7 +183,7 @@ static void rtc_periodic_timer(void *opaque)
             if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
                 s->irq_reinject_on_ack_count = 0;		
             apic_reset_irq_delivered();
-            rtc_irq_raise(s->irq);
+            qemu_irq_raise(s->irq);
             if (!apic_get_irq_delivered()) {
                 s->irq_coalesced++;
                 rtc_coalesced_timer_update(s);
@@ -215,7 +192,7 @@ static void rtc_periodic_timer(void *opaque)
             }
         } else
 #endif
-        rtc_irq_raise(s->irq);
+        qemu_irq_raise(s->irq);
     }
     if (s->cmos_data[RTC_REG_B] & REG_B_SQWE) {
         /* Not square wave at all but we don't want 2048Hz interrupts!
@@ -444,15 +421,15 @@ static void rtc_update_second2(void *opaque)
              s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) {
 
             s->cmos_data[RTC_REG_C] |= 0xa0;
-            rtc_irq_raise(s->irq);
+            qemu_irq_raise(s->irq);
         }
     }
 
     /* update ended interrupt */
     s->cmos_data[RTC_REG_C] |= REG_C_UF;
     if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
-      s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
-      rtc_irq_raise(s->irq);
+        s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
+        qemu_irq_raise(s->irq);
     }
 
     /* clear update in progress bit */
@@ -606,9 +583,6 @@ static int rtc_initfn(ISADevice *dev)
 {
     RTCState *s = DO_UPCAST(RTCState, dev, dev);
     int base = 0x70;
-    int isairq = 8;
-
-    isa_init_irq(dev, &s->irq, isairq);
 
     s->cmos_data[RTC_REG_A] = 0x26;
     s->cmos_data[RTC_REG_B] = 0x02;
@@ -638,13 +612,20 @@ static int rtc_initfn(ISADevice *dev)
     return 0;
 }
 
-ISADevice *rtc_init(int base_year)
+ISADevice *rtc_init(int base_year, qemu_irq intercept_irq)
 {
     ISADevice *dev;
+    RTCState *s;
 
     dev = isa_create("mc146818rtc");
+    s = DO_UPCAST(RTCState, dev, dev);
     qdev_prop_set_int32(&dev->qdev, "base_year", base_year);
     qdev_init_nofail(&dev->qdev);
+    if (intercept_irq) {
+        s->irq = intercept_irq;
+    } else {
+        isa_init_irq(dev, &s->irq, RTC_ISA_IRQ);
+    }
     return dev;
 }
 
diff --git a/hw/mc146818rtc.h b/hw/mc146818rtc.h
index 6f46a68..575968c 100644
--- a/hw/mc146818rtc.h
+++ b/hw/mc146818rtc.h
@@ -3,7 +3,9 @@
 
 #include "isa.h"
 
-ISADevice *rtc_init(int base_year);
+#define RTC_ISA_IRQ 8
+
+ISADevice *rtc_init(int base_year, qemu_irq intercept_irq);
 void rtc_set_memory(ISADevice *dev, int addr, int val);
 void rtc_set_date(ISADevice *dev, const struct tm *tm);
 
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index ead3a00..22db7a2 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -259,7 +259,7 @@ void mips_jazz_init (ram_addr_t ram_size,
     fdctrl_init_sysbus(rc4030[1], 0, 0x80003000, fds);
 
     /* Real time clock */
-    rtc_init(1980);
+    rtc_init(1980, NULL);
     s_rtc = cpu_register_io_memory(rtc_read, rtc_write, NULL);
     cpu_register_physical_memory(0x80004000, 0x00001000, s_rtc);
 
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index a8f9d15..23de7f0 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -959,7 +959,7 @@ void mips_malta_init (ram_addr_t ram_size,
     /* Super I/O */
     isa_dev = isa_create_simple("i8042");
  
-    rtc_state = rtc_init(2000);
+    rtc_state = rtc_init(2000, NULL);
     serial_isa_init(0, serial_hds[0]);
     serial_isa_init(1, serial_hds[1]);
     if (parallel_hds[0])
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index f1fcfcd..5a96dea 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -267,7 +267,7 @@ void mips_r4k_init (ram_addr_t ram_size,
     isa_bus_new(NULL);
     isa_bus_irqs(i8259);
 
-    rtc_state = rtc_init(2000);
+    rtc_state = rtc_init(2000, NULL);
 
     /* Register 64 KB of ISA IO space at 0x14000000 */
 #ifdef TARGET_WORDS_BIGENDIAN
diff --git a/hw/pc.c b/hw/pc.c
index ae31e2e..1491129 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -943,6 +943,7 @@ void pc_basic_device_init(qemu_irq *isa_irq,
     int i;
     DriveInfo *fd[MAX_FD];
     PITState *pit;
+    qemu_irq rtc_irq = NULL;
     qemu_irq *a20_line;
     ISADevice *i8042;
     qemu_irq *cpu_exit_irq;
@@ -951,19 +952,20 @@ void pc_basic_device_init(qemu_irq *isa_irq,
 
     register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
 
-    *rtc_state = rtc_init(2000);
-
-    qemu_register_boot_set(pc_boot_set, *rtc_state);
-
-    pit = pit_init(0x40, isa_reserve_irq(0));
-    pcspk_init(pit);
     if (!no_hpet) {
         DeviceState *hpet = sysbus_create_simple("hpet", HPET_BASE, NULL);
 
         for (i = 0; i < 24; i++) {
             sysbus_connect_irq(sysbus_from_qdev(hpet), i, isa_irq[i]);
         }
+        rtc_irq = qdev_get_gpio_in(hpet, 0);
     }
+    *rtc_state = rtc_init(2000, rtc_irq);
+
+    qemu_register_boot_set(pc_boot_set, *rtc_state);
+
+    pit = pit_init(0x40, isa_reserve_irq(0));
+    pcspk_init(pit);
 
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         if (serial_hds[i]) {
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 16c9950..bb9e15f 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -696,7 +696,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
     pci_vga_init(pci_bus, 0, 0);
     //    openpic = openpic_init(0x00000000, 0xF0000000, 1);
     //    pit = pit_init(0x40, i8259[0]);
-    rtc_init(2000);
+    rtc_init(2000, NULL);
 
     if (serial_hds[0])
         serial_isa_init(0, serial_hds[0]);
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 08/13] hpet: Drop static state
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
                   ` (6 preceding siblings ...)
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 07/13] hpet/rtc: Rework RTC IRQ replacement by HPET Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 09/13] hpet: Add support for level-triggered interrupts Jan Kiszka
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

Instead of keeping a static reference around, pass the state to
hpet_enabled and hpet_get_ticks. All callers now have it at hand. Will
once allow to instantiate the HPET more than a single time.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/hpet.c |   38 +++++++++++++++++---------------------
 1 files changed, 17 insertions(+), 21 deletions(-)

diff --git a/hw/hpet.c b/hw/hpet.c
index edfe02e..59a06f6 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -69,8 +69,6 @@ typedef struct HPETState {
     uint64_t hpet_counter;      /* main counter */
 } HPETState;
 
-static HPETState *hpet_statep;
-
 static uint32_t hpet_in_legacy_mode(HPETState *s)
 {
     return s->config & HPET_CFG_LEGACY;
@@ -81,9 +79,9 @@ static uint32_t timer_int_route(struct HPETTimer *timer)
     return (timer->config & HPET_TN_INT_ROUTE_MASK) >> HPET_TN_INT_ROUTE_SHIFT;
 }
 
-static uint32_t hpet_enabled(void)
+static uint32_t hpet_enabled(HPETState *s)
 {
-    return hpet_statep->config & HPET_CFG_ENABLE;
+    return s->config & HPET_CFG_ENABLE;
 }
 
 static uint32_t timer_is_periodic(HPETTimer *t)
@@ -133,9 +131,9 @@ static int deactivating_bit(uint64_t old, uint64_t new, uint64_t mask)
     return ((old & mask) && !(new & mask));
 }
 
-static uint64_t hpet_get_ticks(void)
+static uint64_t hpet_get_ticks(HPETState *s)
 {
-    return ns_to_ticks(qemu_get_clock(vm_clock) + hpet_statep->hpet_offset);
+    return ns_to_ticks(qemu_get_clock(vm_clock) + s->hpet_offset);
 }
 
 /*
@@ -174,7 +172,7 @@ static void update_irq(struct HPETTimer *timer)
     } else {
         route = timer_int_route(timer);
     }
-    if (!timer_enabled(timer) || !hpet_enabled()) {
+    if (!timer_enabled(timer) || !hpet_enabled(timer->state)) {
         return;
     }
     qemu_irq_pulse(timer->state->irqs[route]);
@@ -185,7 +183,7 @@ static void hpet_pre_save(void *opaque)
     HPETState *s = opaque;
 
     /* save current counter value */
-    s->hpet_counter = hpet_get_ticks();
+    s->hpet_counter = hpet_get_ticks(s);
 }
 
 static int hpet_post_load(void *opaque, int version_id)
@@ -240,7 +238,7 @@ static void hpet_timer(void *opaque)
     uint64_t diff;
 
     uint64_t period = t->period;
-    uint64_t cur_tick = hpet_get_ticks();
+    uint64_t cur_tick = hpet_get_ticks(t->state);
 
     if (timer_is_periodic(t) && period != 0) {
         if (t->config & HPET_TN_32BIT) {
@@ -270,7 +268,7 @@ static void hpet_set_timer(HPETTimer *t)
 {
     uint64_t diff;
     uint32_t wrap_diff;  /* how many ticks until we wrap? */
-    uint64_t cur_tick = hpet_get_ticks();
+    uint64_t cur_tick = hpet_get_ticks(t->state);
 
     /* whenever new timer is being set up, make sure wrap_flag is 0 */
     t->wrap_flag = 0;
@@ -353,16 +351,16 @@ static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
             DPRINTF("qemu: invalid HPET_CFG + 4 hpet_ram_readl \n");
             return 0;
         case HPET_COUNTER:
-            if (hpet_enabled()) {
-                cur_tick = hpet_get_ticks();
+            if (hpet_enabled(s)) {
+                cur_tick = hpet_get_ticks(s);
             } else {
                 cur_tick = s->hpet_counter;
             }
             DPRINTF("qemu: reading counter  = %" PRIx64 "\n", cur_tick);
             return cur_tick;
         case HPET_COUNTER + 4:
-            if (hpet_enabled()) {
-                cur_tick = hpet_get_ticks();
+            if (hpet_enabled(s)) {
+                cur_tick = hpet_get_ticks(s);
             } else {
                 cur_tick = s->hpet_counter;
             }
@@ -457,7 +455,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
                     (timer->period & 0xffffffff00000000ULL) | new_val;
             }
             timer->config &= ~HPET_TN_SETVAL;
-            if (hpet_enabled()) {
+            if (hpet_enabled(s)) {
                 hpet_set_timer(timer);
             }
             break;
@@ -476,7 +474,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
                     (timer->period & 0xffffffffULL) | new_val << 32;
                 }
                 timer->config &= ~HPET_TN_SETVAL;
-                if (hpet_enabled()) {
+                if (hpet_enabled(s)) {
                     hpet_set_timer(timer);
                 }
                 break;
@@ -506,7 +504,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
                 }
             } else if (deactivating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
                 /* Halt main counter and disable interrupt generation. */
-                s->hpet_counter = hpet_get_ticks();
+                s->hpet_counter = hpet_get_ticks(s);
                 for (i = 0; i < HPET_NUM_TIMERS; i++) {
                     hpet_del_timer(&s->timer[i]);
                 }
@@ -527,7 +525,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
             /* FIXME: need to handle level-triggered interrupts */
             break;
         case HPET_COUNTER:
-            if (hpet_enabled()) {
+            if (hpet_enabled(s)) {
                 DPRINTF("qemu: Writing counter while HPET enabled!\n");
             }
             s->hpet_counter =
@@ -536,7 +534,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
                     value, s->hpet_counter);
             break;
         case HPET_COUNTER + 4:
-            if (hpet_enabled()) {
+            if (hpet_enabled(s)) {
                 DPRINTF("qemu: Writing counter while HPET enabled!\n");
             }
             s->hpet_counter =
@@ -624,8 +622,6 @@ static int hpet_init(SysBusDevice *dev)
     int i, iomemtype;
     HPETTimer *timer;
 
-    assert(!hpet_statep);
-    hpet_statep = s;
     for (i = 0; i < HPET_NUM_IRQ_ROUTES; i++) {
         sysbus_init_irq(dev, &s->irqs[i]);
     }
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 09/13] hpet: Add support for level-triggered interrupts
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
                   ` (7 preceding siblings ...)
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 08/13] hpet: Drop static state Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 10/13] vmstate: Add VMSTATE_STRUCT_VARRAY_UINT8 Jan Kiszka
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

By implementing this feature we can also remove a nasty way to kill qemu
(by trying to enable level-triggered hpet interrupts).

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/hpet.c |   32 ++++++++++++++++++++++----------
 1 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/hw/hpet.c b/hw/hpet.c
index 59a06f6..f24b227 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -159,8 +159,10 @@ static inline uint64_t hpet_calculate_diff(HPETTimer *t, uint64_t current)
     }
 }
 
-static void update_irq(struct HPETTimer *timer)
+static void update_irq(struct HPETTimer *timer, int set)
 {
+    uint64_t mask;
+    HPETState *s;
     int route;
 
     if (timer->tn <= 1 && hpet_in_legacy_mode(timer->state)) {
@@ -172,10 +174,18 @@ static void update_irq(struct HPETTimer *timer)
     } else {
         route = timer_int_route(timer);
     }
-    if (!timer_enabled(timer) || !hpet_enabled(timer->state)) {
-        return;
+    s = timer->state;
+    mask = 1 << timer->tn;
+    if (!set || !timer_enabled(timer) || !hpet_enabled(timer->state)) {
+        s->isr &= ~mask;
+        qemu_irq_lower(s->irqs[route]);
+    } else if (timer->config & HPET_TN_TYPE_LEVEL) {
+        s->isr |= mask;
+        qemu_irq_raise(s->irqs[route]);
+    } else {
+        s->isr &= ~mask;
+        qemu_irq_pulse(s->irqs[route]);
     }
-    qemu_irq_pulse(timer->state->irqs[route]);
 }
 
 static void hpet_pre_save(void *opaque)
@@ -261,7 +271,7 @@ static void hpet_timer(void *opaque)
             t->wrap_flag = 0;
         }
     }
-    update_irq(t);
+    update_irq(t, 1);
 }
 
 static void hpet_set_timer(HPETTimer *t)
@@ -291,6 +301,7 @@ static void hpet_set_timer(HPETTimer *t)
 static void hpet_del_timer(HPETTimer *t)
 {
     qemu_del_timer(t->qemu_timer);
+    update_irq(t, 0);
 }
 
 #ifdef HPET_DEBUG
@@ -423,10 +434,6 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
                 timer->cmp = (uint32_t)timer->cmp;
                 timer->period = (uint32_t)timer->period;
             }
-            if (new_val & HPET_TN_TYPE_LEVEL) {
-                printf("qemu: level-triggered hpet not supported\n");
-                exit (-1);
-            }
             if (activating_bit(old_val, new_val, HPET_TN_ENABLE)) {
                 hpet_set_timer(timer);
             } else if (deactivating_bit(old_val, new_val, HPET_TN_ENABLE)) {
@@ -522,7 +529,12 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
             DPRINTF("qemu: invalid HPET_CFG+4 write \n");
             break;
         case HPET_STATUS:
-            /* FIXME: need to handle level-triggered interrupts */
+            val = new_val & s->isr;
+            for (i = 0; i < HPET_NUM_TIMERS; i++) {
+                if (val & (1 << i)) {
+                    update_irq(&s->timer[i], 0);
+                }
+            }
             break;
         case HPET_COUNTER:
             if (hpet_enabled(s)) {
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 10/13] vmstate: Add VMSTATE_STRUCT_VARRAY_UINT8
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
                   ` (8 preceding siblings ...)
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 09/13] hpet: Add support for level-triggered interrupts Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 11/13] hpet: Make number of timers configurable Jan Kiszka
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

Required for hpet.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/hw.h |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/hw/hw.h b/hw/hw.h
index fc2d184..36be0be 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -474,6 +474,16 @@ extern const VMStateInfo vmstate_info_unused_buffer;
     .offset     = vmstate_offset_array(_state, _field, _type, _num), \
 }
 
+#define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \
+    .name       = (stringify(_field)),                               \
+    .num_offset = vmstate_offset_value(_state, _field_num, uint8_t),  \
+    .version_id = (_version),                                        \
+    .vmsd       = &(_vmsd),                                          \
+    .size       = sizeof(_type),                                     \
+    .flags      = VMS_STRUCT|VMS_VARRAY_INT32,                       \
+    .offset     = offsetof(_state, _field),                          \
+}
+
 #define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \
     .name         = (stringify(_field)),                             \
     .version_id   = (_version),                                      \
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 11/13] hpet: Make number of timers configurable
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
                   ` (9 preceding siblings ...)
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 10/13] vmstate: Add VMSTATE_STRUCT_VARRAY_UINT8 Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 12/13] hpet: Add MSI support Jan Kiszka
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

One HPET block supports up to 32 timers. Allow to instantiate more than
the recommended and implemented minimum of 3. The number is configured
via the qdev property "timers". It is also saved/restored so that it
need not match between migration peers.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/hpet.c      |   53 ++++++++++++++++++++++++++++++++++++++++-------------
 hw/hpet_emul.h |    6 +++++-
 2 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/hw/hpet.c b/hw/hpet.c
index f24b227..6187e5e 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -60,7 +60,8 @@ typedef struct HPETState {
     uint64_t hpet_offset;
     qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
     uint8_t rtc_irq_level;
-    HPETTimer timer[HPET_NUM_TIMERS];
+    uint8_t num_timers;
+    HPETTimer timer[HPET_MAX_TIMERS];
 
     /* Memory-mapped, software visible registers */
     uint64_t capability;        /* capabilities */
@@ -196,12 +197,25 @@ static void hpet_pre_save(void *opaque)
     s->hpet_counter = hpet_get_ticks(s);
 }
 
+static int hpet_pre_load(void *opaque)
+{
+    HPETState *s = opaque;
+
+    /* version 1 only supports 3, later versions will load the actual value */
+    s->num_timers = HPET_MIN_TIMERS;
+    return 0;
+}
+
 static int hpet_post_load(void *opaque, int version_id)
 {
     HPETState *s = opaque;
 
     /* Recalculate the offset between the main counter and guest time */
     s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_get_clock(vm_clock);
+
+    /* Push number of timers into capability returned via HPET_ID */
+    s->capability &= ~HPET_ID_NUM_TIM_MASK;
+    s->capability |= (s->num_timers - 1) << HPET_ID_NUM_TIM_SHIFT;
     return 0;
 }
 
@@ -224,17 +238,19 @@ static const VMStateDescription vmstate_hpet_timer = {
 
 static const VMStateDescription vmstate_hpet = {
     .name = "hpet",
-    .version_id = 1,
+    .version_id = 2,
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .pre_save = hpet_pre_save,
+    .pre_load = hpet_pre_load,
     .post_load = hpet_post_load,
     .fields      = (VMStateField []) {
         VMSTATE_UINT64(config, HPETState),
         VMSTATE_UINT64(isr, HPETState),
         VMSTATE_UINT64(hpet_counter, HPETState),
-        VMSTATE_STRUCT_ARRAY(timer, HPETState, HPET_NUM_TIMERS, 0,
-                             vmstate_hpet_timer, HPETTimer),
+        VMSTATE_UINT8_V(num_timers, HPETState, 2),
+        VMSTATE_STRUCT_VARRAY_UINT8(timer, HPETState, num_timers, 0,
+                                    vmstate_hpet_timer, HPETTimer),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -330,7 +346,7 @@ static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
         uint8_t timer_id = (addr - 0x100) / 0x20;
         HPETTimer *timer = &s->timer[timer_id];
 
-        if (timer_id > HPET_NUM_TIMERS - 1) {
+        if (timer_id > s->num_timers) {
             DPRINTF("qemu: timer id out of range\n");
             return 0;
         }
@@ -421,7 +437,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
         HPETTimer *timer = &s->timer[timer_id];
 
         DPRINTF("qemu: hpet_ram_writel timer_id = %#x \n", timer_id);
-        if (timer_id > HPET_NUM_TIMERS - 1) {
+        if (timer_id > s->num_timers) {
             DPRINTF("qemu: timer id out of range\n");
             return;
         }
@@ -504,7 +520,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
                 /* Enable main counter and interrupt generation. */
                 s->hpet_offset =
                     ticks_to_ns(s->hpet_counter) - qemu_get_clock(vm_clock);
-                for (i = 0; i < HPET_NUM_TIMERS; i++) {
+                for (i = 0; i < s->num_timers; i++) {
                     if ((&s->timer[i])->cmp != ~0ULL) {
                         hpet_set_timer(&s->timer[i]);
                     }
@@ -512,7 +528,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
             } else if (deactivating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
                 /* Halt main counter and disable interrupt generation. */
                 s->hpet_counter = hpet_get_ticks(s);
-                for (i = 0; i < HPET_NUM_TIMERS; i++) {
+                for (i = 0; i < s->num_timers; i++) {
                     hpet_del_timer(&s->timer[i]);
                 }
             }
@@ -530,7 +546,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
             break;
         case HPET_STATUS:
             val = new_val & s->isr;
-            for (i = 0; i < HPET_NUM_TIMERS; i++) {
+            for (i = 0; i < s->num_timers; i++) {
                 if (val & (1 << i)) {
                     update_irq(&s->timer[i], 0);
                 }
@@ -589,7 +605,7 @@ static void hpet_reset(DeviceState *d)
     int i;
     static int count = 0;
 
-    for (i = 0; i < HPET_NUM_TIMERS; i++) {
+    for (i = 0; i < s->num_timers; i++) {
         HPETTimer *timer = &s->timer[i];
 
         hpet_del_timer(timer);
@@ -603,8 +619,9 @@ static void hpet_reset(DeviceState *d)
 
     s->hpet_counter = 0ULL;
     s->hpet_offset = 0ULL;
-    /* 64-bit main counter; 3 timers supported; LegacyReplacementRoute. */
-    s->capability = 0x8086a201ULL;
+    /* 64-bit main counter; LegacyReplacementRoute. */
+    s->capability = 0x8086a001ULL;
+    s->capability |= (s->num_timers - 1) << HPET_ID_NUM_TIM_SHIFT;
     s->capability |= ((HPET_CLK_PERIOD) << 32);
     s->config = 0ULL;
     if (count > 0) {
@@ -637,7 +654,13 @@ static int hpet_init(SysBusDevice *dev)
     for (i = 0; i < HPET_NUM_IRQ_ROUTES; i++) {
         sysbus_init_irq(dev, &s->irqs[i]);
     }
-    for (i = 0; i < HPET_NUM_TIMERS; i++) {
+
+    if (s->num_timers < HPET_MIN_TIMERS) {
+        s->num_timers = HPET_MIN_TIMERS;
+    } else if (s->num_timers > HPET_MAX_TIMERS) {
+        s->num_timers = HPET_MAX_TIMERS;
+    }
+    for (i = 0; i < HPET_MAX_TIMERS; i++) {
         timer = &s->timer[i];
         timer->qemu_timer = qemu_new_timer(vm_clock, hpet_timer, timer);
         timer->tn = i;
@@ -661,6 +684,10 @@ static SysBusDeviceInfo hpet_device_info = {
     .qdev.vmsd    = &vmstate_hpet,
     .qdev.reset   = hpet_reset,
     .init         = hpet_init,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS),
+        DEFINE_PROP_END_OF_LIST(),
+    },
 };
 
 static void hpet_register_device(void)
diff --git a/hw/hpet_emul.h b/hw/hpet_emul.h
index 9c268cc..e8b794c 100644
--- a/hw/hpet_emul.h
+++ b/hw/hpet_emul.h
@@ -17,7 +17,8 @@
 #define HPET_CLK_PERIOD         10000000ULL /* 10000000 femtoseconds == 10ns*/
 
 #define FS_PER_NS 1000000
-#define HPET_NUM_TIMERS 3
+#define HPET_MIN_TIMERS         3
+#define HPET_MAX_TIMERS         32
 
 #define HPET_NUM_IRQ_ROUTES     32
 
@@ -34,6 +35,9 @@
 #define HPET_TN_ROUTE   0x010
 #define HPET_CFG_WRITE_MASK  0x3
 
+#define HPET_ID_NUM_TIM_SHIFT   8
+#define HPET_ID_NUM_TIM_MASK    0x1f00
+
 #define HPET_TN_TYPE_LEVEL       0x002
 #define HPET_TN_ENABLE           0x004
 #define HPET_TN_PERIODIC         0x008
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 12/13] hpet: Add MSI support
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
                   ` (10 preceding siblings ...)
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 11/13] hpet: Make number of timers configurable Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 13/13] monitor/QMP: Drop info hpet / query-hpet Jan Kiszka
  2010-06-13 13:21 ` [Qemu-devel] Re: [PATCH v4 00/13] HPET cleanups, fixes, enhancements Blue Swirl
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

This implements the HPET capability of routing IRQs to the front-side
bus, aka MSI support. This feature can be enabled via the qdev property
"msi" and is off by default.

Note that switching it on can cause guests (at least Linux) to use the
HPET as timer instead of the LAPIC. KVM users should recall that only
the latter is currently available as fast in-kernel model.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/hpet.c      |   38 ++++++++++++++++++++++++++++++++++----
 hw/hpet_emul.h |    4 +++-
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/hw/hpet.c b/hw/hpet.c
index 6187e5e..93fc399 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -39,6 +39,8 @@
 #define DPRINTF(...)
 #endif
 
+#define HPET_MSI_SUPPORT        0
+
 struct HPETState;
 typedef struct HPETTimer {  /* timers */
     uint8_t tn;             /*timer number*/
@@ -47,7 +49,7 @@ typedef struct HPETTimer {  /* timers */
     /* Memory-mapped, software visible timer registers */
     uint64_t config;        /* configuration/cap */
     uint64_t cmp;           /* comparator */
-    uint64_t fsb;           /* FSB route, not supported now */
+    uint64_t fsb;           /* FSB route */
     /* Hidden register state */
     uint64_t period;        /* Last value written to comparator */
     uint8_t wrap_flag;      /* timer pop will indicate wrap for one-shot 32-bit
@@ -59,6 +61,7 @@ typedef struct HPETState {
     SysBusDevice busdev;
     uint64_t hpet_offset;
     qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
+    uint32_t flags;
     uint8_t rtc_irq_level;
     uint8_t num_timers;
     HPETTimer timer[HPET_MAX_TIMERS];
@@ -80,6 +83,11 @@ static uint32_t timer_int_route(struct HPETTimer *timer)
     return (timer->config & HPET_TN_INT_ROUTE_MASK) >> HPET_TN_INT_ROUTE_SHIFT;
 }
 
+static uint32_t timer_fsb_route(HPETTimer *t)
+{
+    return t->config & HPET_TN_FSB_ENABLE;
+}
+
 static uint32_t hpet_enabled(HPETState *s)
 {
     return s->config & HPET_CFG_ENABLE;
@@ -179,7 +187,11 @@ static void update_irq(struct HPETTimer *timer, int set)
     mask = 1 << timer->tn;
     if (!set || !timer_enabled(timer) || !hpet_enabled(timer->state)) {
         s->isr &= ~mask;
-        qemu_irq_lower(s->irqs[route]);
+        if (!timer_fsb_route(timer)) {
+            qemu_irq_lower(s->irqs[route]);
+        }
+    } else if (timer_fsb_route(timer)) {
+        stl_phys(timer->fsb >> 32, timer->fsb & 0xffffffff);
     } else if (timer->config & HPET_TN_TYPE_LEVEL) {
         s->isr |= mask;
         qemu_irq_raise(s->irqs[route]);
@@ -216,6 +228,12 @@ static int hpet_post_load(void *opaque, int version_id)
     /* Push number of timers into capability returned via HPET_ID */
     s->capability &= ~HPET_ID_NUM_TIM_MASK;
     s->capability |= (s->num_timers - 1) << HPET_ID_NUM_TIM_SHIFT;
+
+    /* Derive HPET_MSI_SUPPORT from the capability of the first timer. */
+    s->flags &= ~(1 << HPET_MSI_SUPPORT);
+    if (s->timer[0].config & HPET_TN_FSB_CAP) {
+        s->flags |= 1 << HPET_MSI_SUPPORT;
+    }
     return 0;
 }
 
@@ -361,6 +379,8 @@ static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
         case HPET_TN_CMP + 4:
             return timer->cmp >> 32;
         case HPET_TN_ROUTE:
+            return timer->fsb;
+        case HPET_TN_ROUTE + 4:
             return timer->fsb >> 32;
         default:
             DPRINTF("qemu: invalid hpet_ram_readl\n");
@@ -444,6 +464,9 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
         switch ((addr - 0x100) % 0x20) {
         case HPET_TN_CFG:
             DPRINTF("qemu: hpet_ram_writel HPET_TN_CFG\n");
+            if (activating_bit(old_val, new_val, HPET_TN_FSB_ENABLE)) {
+                update_irq(timer, 0);
+            }
             val = hpet_fixup_reg(new_val, old_val, HPET_TN_CFG_WRITE_MASK);
             timer->config = (timer->config & 0xffffffff00000000ULL) | val;
             if (new_val & HPET_TN_32BIT) {
@@ -501,8 +524,11 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
                     hpet_set_timer(timer);
                 }
                 break;
+        case HPET_TN_ROUTE:
+            timer->fsb = (timer->fsb & 0xffffffff00000000ULL) | new_val;
+            break;
         case HPET_TN_ROUTE + 4:
-            DPRINTF("qemu: hpet_ram_writel HPET_TN_ROUTE + 4\n");
+            timer->fsb = (new_val << 32) | (timer->fsb & 0xffffffff);
             break;
         default:
             DPRINTF("qemu: invalid hpet_ram_writel\n");
@@ -610,7 +636,10 @@ static void hpet_reset(DeviceState *d)
 
         hpet_del_timer(timer);
         timer->cmp = ~0ULL;
-        timer->config =  HPET_TN_PERIODIC_CAP | HPET_TN_SIZE_CAP;
+        timer->config = HPET_TN_PERIODIC_CAP | HPET_TN_SIZE_CAP;
+        if (s->flags & (1 << HPET_MSI_SUPPORT)) {
+            timer->config |= HPET_TN_FSB_CAP;
+        }
         /* advertise availability of ioapic inti2 */
         timer->config |=  0x00000004ULL << 32;
         timer->period = 0ULL;
@@ -686,6 +715,7 @@ static SysBusDeviceInfo hpet_device_info = {
     .init         = hpet_init,
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS),
+        DEFINE_PROP_BIT("msi", HPETState, flags, HPET_MSI_SUPPORT, false),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
diff --git a/hw/hpet_emul.h b/hw/hpet_emul.h
index e8b794c..d7bc102 100644
--- a/hw/hpet_emul.h
+++ b/hw/hpet_emul.h
@@ -46,7 +46,9 @@
 #define HPET_TN_SETVAL           0x040
 #define HPET_TN_32BIT            0x100
 #define HPET_TN_INT_ROUTE_MASK  0x3e00
-#define HPET_TN_CFG_WRITE_MASK  0x3f4e
+#define HPET_TN_FSB_ENABLE      0x4000
+#define HPET_TN_FSB_CAP         0x8000
+#define HPET_TN_CFG_WRITE_MASK  0x7f4e
 #define HPET_TN_INT_ROUTE_SHIFT      9
 #define HPET_TN_INT_ROUTE_CAP_SHIFT 32
 #define HPET_TN_CFG_BITS_READONLY_OR_RESERVED 0xffff80b1U
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v4 13/13] monitor/QMP: Drop info hpet / query-hpet
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
                   ` (11 preceding siblings ...)
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 12/13] hpet: Add MSI support Jan Kiszka
@ 2010-06-13 12:15 ` Jan Kiszka
  2010-06-13 13:21 ` [Qemu-devel] Re: [PATCH v4 00/13] HPET cleanups, fixes, enhancements Blue Swirl
  13 siblings, 0 replies; 15+ messages in thread
From: Jan Kiszka @ 2010-06-13 12:15 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: blue Swirl, Jan Kiszka, Paul Brook, Gleb Natapov, Juan Quintela

From: Jan Kiszka <jan.kiszka@siemens.com>

This command was of minimal use before, now it is useless as the hpet
become a qdev device and is thus easily discoverable. We should
definitely not set query-hpet in QMP's stone, and there is also no good
reason to keep it for the interactive monitor.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 QMP/vm-info     |    2 +-
 monitor.c       |   22 ----------------------
 qemu-monitor.hx |   21 ---------------------
 3 files changed, 1 insertions(+), 44 deletions(-)

diff --git a/QMP/vm-info b/QMP/vm-info
index b150d82..8ebaeb3 100755
--- a/QMP/vm-info
+++ b/QMP/vm-info
@@ -25,7 +25,7 @@ def main():
     qemu = qmp.QEMUMonitorProtocol(argv[1])
     qemu.connect()
 
-    for cmd in [ 'version', 'hpet', 'kvm', 'status', 'uuid', 'balloon' ]:
+    for cmd in [ 'version', 'kvm', 'status', 'uuid', 'balloon' ]:
         print cmd + ': ' + str(qemu.send('query-' + cmd))
 
 if __name__ == '__main__':
diff --git a/monitor.c b/monitor.c
index 15b53b9..14f77bd 100644
--- a/monitor.c
+++ b/monitor.c
@@ -740,20 +740,6 @@ static void do_info_commands(Monitor *mon, QObject **ret_data)
     *ret_data = QOBJECT(cmd_list);
 }
 
-#if defined(TARGET_I386)
-static void do_info_hpet_print(Monitor *mon, const QObject *data)
-{
-    monitor_printf(mon, "HPET is %s by QEMU\n",
-                   qdict_get_bool(qobject_to_qdict(data), "enabled") ?
-                   "enabled" : "disabled");
-}
-
-static void do_info_hpet(Monitor *mon, QObject **ret_data)
-{
-    *ret_data = qobject_from_jsonf("{ 'enabled': %i }", !no_hpet);
-}
-#endif
-
 static void do_info_uuid_print(Monitor *mon, const QObject *data)
 {
     monitor_printf(mon, "%s\n", qdict_get_str(qobject_to_qdict(data), "UUID"));
@@ -2509,14 +2495,6 @@ static const mon_cmd_t info_cmds[] = {
         .help       = "show the active virtual memory mappings",
         .mhandler.info = mem_info,
     },
-    {
-        .name       = "hpet",
-        .args_type  = "",
-        .params     = "",
-        .help       = "show state of HPET",
-        .user_print = do_info_hpet_print,
-        .mhandler.info_new = do_info_hpet,
-    },
 #endif
     {
         .name       = "jit",
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index f6a94f2..9f62b94 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -2144,27 +2144,6 @@ show the active virtual memory mappings (i386 only)
 ETEXI
 
 STEXI
-@item info hpet
-show state of HPET (i386 only)
-ETEXI
-SQMP
-query-hpet
-----------
-
-Show HPET state.
-
-Return a json-object with the following information:
-
-- "enabled": true if hpet if enabled, false otherwise (json-bool)
-
-Example:
-
--> { "execute": "query-hpet" }
-<- { "return": { "enabled": true } }
-
-EQMP
-
-STEXI
 @item info jit
 show dynamic compiler info
 @item info kvm
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] Re: [PATCH v4 00/13] HPET cleanups, fixes, enhancements
  2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
                   ` (12 preceding siblings ...)
  2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 13/13] monitor/QMP: Drop info hpet / query-hpet Jan Kiszka
@ 2010-06-13 13:21 ` Blue Swirl
  13 siblings, 0 replies; 15+ messages in thread
From: Blue Swirl @ 2010-06-13 13:21 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Anthony Liguori, Paul Brook, qemu-devel, Gleb Natapov, Juan Quintela

Thanks, applied all.

On Sun, Jun 13, 2010 at 12:15 PM, Jan Kiszka <jan.kiszka@web.de> wrote:
> As the discussion around how to extend the IRQ framework /wrt
> de-coalescing or message passing support still hasn't settled yet, this
> series now skips the related changes, just focusing on the HPET. No
> further changes compared to v3. Please merge.
>
> Jan Kiszka (13):
>  hpet: Catch out-of-bounds timer access
>  hpet: Coding style cleanups and some refactorings
>  hpet: Silence warning on write to running main counter
>  hpet: Move static timer field initialization
>  hpet: Convert to qdev
>  hpet: Start/stop timer when HPET_TN_ENABLE is modified
>  hpet/rtc: Rework RTC IRQ replacement by HPET
>  hpet: Drop static state
>  hpet: Add support for level-triggered interrupts
>  vmstate: Add VMSTATE_STRUCT_VARRAY_UINT8
>  hpet: Make number of timers configurable
>  hpet: Add MSI support
>  monitor/QMP: Drop info hpet / query-hpet
>
>  QMP/vm-info      |    2 +-
>  hw/hpet.c        |  580 +++++++++++++++++++++++++++++++++--------------------
>  hw/hpet_emul.h   |   46 +----
>  hw/hw.h          |   10 +
>  hw/mc146818rtc.c |   49 ++----
>  hw/mc146818rtc.h |    4 +-
>  hw/mips_jazz.c   |    2 +-
>  hw/mips_malta.c  |    2 +-
>  hw/mips_r4k.c    |    2 +-
>  hw/pc.c          |   15 +-
>  hw/ppc_prep.c    |    2 +-
>  monitor.c        |   22 --
>  qemu-monitor.hx  |   21 --
>  13 files changed, 415 insertions(+), 342 deletions(-)
>
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2010-06-13 13:21 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-13 12:15 [Qemu-devel] [PATCH v4 00/13] HPET cleanups, fixes, enhancements Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 01/13] hpet: Catch out-of-bounds timer access Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 02/13] hpet: Coding style cleanups and some refactorings Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 03/13] hpet: Silence warning on write to running main counter Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 04/13] hpet: Move static timer field initialization Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 05/13] hpet: Convert to qdev Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 06/13] hpet: Start/stop timer when HPET_TN_ENABLE is modified Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 07/13] hpet/rtc: Rework RTC IRQ replacement by HPET Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 08/13] hpet: Drop static state Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 09/13] hpet: Add support for level-triggered interrupts Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 10/13] vmstate: Add VMSTATE_STRUCT_VARRAY_UINT8 Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 11/13] hpet: Make number of timers configurable Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 12/13] hpet: Add MSI support Jan Kiszka
2010-06-13 12:15 ` [Qemu-devel] [PATCH v4 13/13] monitor/QMP: Drop info hpet / query-hpet Jan Kiszka
2010-06-13 13:21 ` [Qemu-devel] Re: [PATCH v4 00/13] HPET cleanups, fixes, enhancements Blue Swirl

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.