]> git.proxmox.com Git - qemu.git/blobdiff - hw/pxa2xx_timer.c
Merge remote-tracking branch 'spice/spice.v39' into staging
[qemu.git] / hw / pxa2xx_timer.c
index 0fbd4a898b6643a3757069ce0397fff9d7796fe1..f777a212262c8aaf699dc69689be04eb992f9c47 100644 (file)
@@ -64,7 +64,6 @@ typedef struct PXA2xxTimerInfo PXA2xxTimerInfo;
 
 typedef struct {
     uint32_t value;
-    int level;
     qemu_irq irq;
     QEMUTimer *qtimer;
     int num;
@@ -94,6 +93,7 @@ struct PXA2xxTimerInfo {
     uint32_t reset3;
     uint32_t snapshot;
 
+    qemu_irq irq4;
     PXA2xxTimer4 tm4[8];
 };
 
@@ -171,7 +171,7 @@ static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
             goto badreg;
         return s->tm4[tm].tm.value;
     case OSCR:
-        return s->clock + muldiv64(qemu_get_clock(vm_clock) -
+        return s->clock + muldiv64(qemu_get_clock_ns(vm_clock) -
                         s->lastload, s->freq, get_ticks_per_sec());
     case OSCR11: tm ++;
     case OSCR10: tm ++;
@@ -187,7 +187,7 @@ static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
         if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
             if (s->tm4[tm - 1].freq)
                 s->snapshot = s->tm4[tm - 1].clock + muldiv64(
-                                qemu_get_clock(vm_clock) -
+                                qemu_get_clock_ns(vm_clock) -
                                 s->tm4[tm - 1].lastload,
                                 s->tm4[tm - 1].freq, get_ticks_per_sec());
             else
@@ -196,7 +196,7 @@ static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
 
         if (!s->tm4[tm].freq)
             return s->tm4[tm].clock;
-        return s->tm4[tm].clock + muldiv64(qemu_get_clock(vm_clock) -
+        return s->tm4[tm].clock + muldiv64(qemu_get_clock_ns(vm_clock) -
                         s->tm4[tm].lastload, s->tm4[tm].freq, get_ticks_per_sec());
     case OIER:
         return s->irq_enabled;
@@ -237,7 +237,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
     case OSMR1:  tm ++;
     case OSMR0:
         s->timer[tm].value = value;
-        pxa2xx_timer_update(s, qemu_get_clock(vm_clock));
+        pxa2xx_timer_update(s, qemu_get_clock_ns(vm_clock));
         break;
     case OSMR11: tm ++;
     case OSMR10: tm ++;
@@ -250,11 +250,11 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
         if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
         s->tm4[tm].tm.value = value;
-        pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
+        pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
         break;
     case OSCR:
         s->oldclock = s->clock;
-        s->lastload = qemu_get_clock(vm_clock);
+        s->lastload = qemu_get_clock_ns(vm_clock);
         s->clock = value;
         pxa2xx_timer_update(s, s->lastload);
         break;
@@ -269,7 +269,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
         if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
         s->tm4[tm].oldclock = s->tm4[tm].clock;
-        s->tm4[tm].lastload = qemu_get_clock(vm_clock);
+        s->tm4[tm].lastload = qemu_get_clock_ns(vm_clock);
         s->tm4[tm].clock = value;
         pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
         break;
@@ -277,20 +277,13 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
         s->irq_enabled = value & 0xfff;
         break;
     case OSSR: /* Status register */
+        value &= s->events;
         s->events &= ~value;
-        for (i = 0; i < 4; i ++, value >>= 1) {
-            if (s->timer[i].level && (value & 1)) {
-                s->timer[i].level = 0;
+        for (i = 0; i < 4; i ++, value >>= 1)
+            if (value & 1)
                 qemu_irq_lower(s->timer[i].irq);
-            }
-        }
-        if (pxa2xx_timer_has_tm4(s)) {
-            for (i = 0; i < 8; i ++, value >>= 1)
-                if (s->tm4[i].tm.level && (value & 1))
-                    s->tm4[i].tm.level = 0;
-            if (!(s->events & 0xff0))
-                qemu_irq_lower(s->tm4->tm.irq);
-        }
+        if (pxa2xx_timer_has_tm4(s) && !(s->events & 0xff0) && value)
+            qemu_irq_lower(s->irq4);
         break;
     case OWER: /* XXX: Reset on OSMR3 match? */
         s->reset3 = value;
@@ -307,7 +300,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
             s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
         else {
             s->tm4[tm].freq = 0;
-            pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
+            pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
         }
         break;
     case OMCR11: tm ++;
@@ -323,7 +316,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
                     pxa2xx_timer4_freq[(value & (1 << 8)) ?  0 : (value & 7)];
         else {
             s->tm4[tm].freq = 0;
-            pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
+            pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
         }
         break;
     default:
@@ -350,7 +343,6 @@ static void pxa2xx_timer_tick(void *opaque)
     PXA2xxTimerInfo *i = t->info;
 
     if (i->irq_enabled & (1 << t->num)) {
-        t->level = 1;
         i->events |= 1 << t->num;
         qemu_irq_raise(t->irq);
     }
@@ -371,7 +363,9 @@ static void pxa2xx_timer_tick4(void *opaque)
     if (t->control & (1 << 3))
         t->clock = 0;
     if (t->control & (1 << 6))
-        pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->tm.num - 4);
+        pxa2xx_timer_update4(i, qemu_get_clock_ns(vm_clock), t->tm.num - 4);
+    if (i->events & 0xff0)
+        qemu_irq_raise(i->irq4);
 }
 
 static int pxa25x_timer_post_load(void *opaque, int version_id)
@@ -380,7 +374,7 @@ static int pxa25x_timer_post_load(void *opaque, int version_id)
     int64_t now;
     int i;
 
-    now = qemu_get_clock(vm_clock);
+    now = qemu_get_clock_ns(vm_clock);
     pxa2xx_timer_update(s, now);
 
     if (pxa2xx_timer_has_tm4(s))
@@ -395,13 +389,12 @@ static int pxa2xx_timer_init(SysBusDevice *dev)
     int i;
     int iomemtype;
     PXA2xxTimerInfo *s;
-    qemu_irq irq4;
 
     s = FROM_SYSBUS(PXA2xxTimerInfo, dev);
     s->irq_enabled = 0;
     s->oldclock = 0;
     s->clock = 0;
-    s->lastload = qemu_get_clock(vm_clock);
+    s->lastload = qemu_get_clock_ns(vm_clock);
     s->reset3 = 0;
 
     for (i = 0; i < 4; i ++) {
@@ -409,23 +402,20 @@ static int pxa2xx_timer_init(SysBusDevice *dev)
         sysbus_init_irq(dev, &s->timer[i].irq);
         s->timer[i].info = s;
         s->timer[i].num = i;
-        s->timer[i].level = 0;
-        s->timer[i].qtimer = qemu_new_timer(vm_clock,
+        s->timer[i].qtimer = qemu_new_timer_ns(vm_clock,
                         pxa2xx_timer_tick, &s->timer[i]);
     }
     if (s->flags & (1 << PXA2XX_TIMER_HAVE_TM4)) {
-        sysbus_init_irq(dev, &irq4);
+        sysbus_init_irq(dev, &s->irq4);
 
         for (i = 0; i < 8; i ++) {
             s->tm4[i].tm.value = 0;
             s->tm4[i].tm.info = s;
             s->tm4[i].tm.num = i + 4;
-            s->tm4[i].tm.level = 0;
             s->tm4[i].freq = 0;
             s->tm4[i].control = 0x0;
-            s->tm4[i].tm.qtimer = qemu_new_timer(vm_clock,
+            s->tm4[i].tm.qtimer = qemu_new_timer_ns(vm_clock,
                         pxa2xx_timer_tick4, &s->tm4[i]);
-            s->tm4[i].tm.irq = irq4;
         }
     }
 
@@ -438,12 +428,11 @@ static int pxa2xx_timer_init(SysBusDevice *dev)
 
 static const VMStateDescription vmstate_pxa2xx_timer0_regs = {
     .name = "pxa2xx_timer0",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(value, PXA2xxTimer0),
-        VMSTATE_INT32(level, PXA2xxTimer0),
         VMSTATE_END_OF_LIST(),
     },
 };