qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [4258] Fix sci irq set when acpi timer about to wrap (Dor Laor, Yaniv Kamay ).
@ 2008-04-26 14:50 Andrzej Zaborowski
  2008-04-27 20:14 ` Avi Kivity
  0 siblings, 1 reply; 3+ messages in thread
From: Andrzej Zaborowski @ 2008-04-26 14:50 UTC (permalink / raw)
  To: qemu-devel

Revision: 4258
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4258
Author:   balrog
Date:     2008-04-26 14:50:48 +0000 (Sat, 26 Apr 2008)

Log Message:
-----------
Fix sci irq set when acpi timer about to wrap (Dor Laor, Yaniv Kamay).

Modified Paths:
--------------
    trunk/hw/acpi.c

Modified: trunk/hw/acpi.c
===================================================================
--- trunk/hw/acpi.c	2008-04-26 14:44:49 UTC (rev 4257)
+++ trunk/hw/acpi.c	2008-04-26 14:50:48 UTC (rev 4258)
@@ -50,12 +50,15 @@
     uint8_t smb_data[32];
     uint8_t smb_index;
     qemu_irq irq;
+    int64_t pmtmr;
 } PIIX4PMState;
 
 #define RTC_EN (1 << 10)
 #define PWRBTN_EN (1 << 8)
 #define GBL_EN (1 << 5)
 #define TMROF_EN (1 << 0)
+#define TIMER_OVERFLOW_CNT (1 << 23)
+#define TIMER_MASK 0xffffffLL
 
 #define SCI_EN (1 << 0)
 
@@ -74,47 +77,61 @@
 
 PIIX4PMState *pm_state;
 
+static void update_pmtmr(PIIX4PMState *s)
+{
+    int64_t pmtmr;
+
+    pmtmr = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec)
+            & TIMER_MASK;
+
+    if (!(s->pmsts & TMROF_EN)) {
+        if ((pmtmr ^ s->pmtmr) & TIMER_OVERFLOW_CNT) {
+            s->pmsts |= TMROF_EN;
+            if (s->pmen & TMROF_EN)
+                qemu_set_irq(s->irq, 1);
+        } else {
+            /* Calculate when the timer will neet to set
+             * the overflow bit again */
+            uint64_t delta = TIMER_OVERFLOW_CNT -
+                    (pmtmr & (TIMER_OVERFLOW_CNT - 1));
+
+            delta = muldiv64(delta, ticks_per_sec, PM_FREQ);
+            qemu_mod_timer(s->tmr_timer, qemu_get_clock(vm_clock) + delta);
+        }
+    }
+
+    s->pmtmr = pmtmr;
+}
+
 static uint32_t get_pmtmr(PIIX4PMState *s)
 {
-    uint32_t d;
-    d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec);
-    return d & 0xffffff;
+    update_pmtmr(s);
+    return s->pmtmr & TIMER_MASK;
 }
 
+
 static int get_pmsts(PIIX4PMState *s)
 {
-    int64_t d;
-    int pmsts;
-    pmsts = s->pmsts;
-    d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec);
-    if (d >= s->tmr_overflow_time)
-        s->pmsts |= TMROF_EN;
-    return pmsts;
+    /* Just increase the accurancy by double computing the timer value */
+    update_pmtmr(s);
+
+    return s->pmsts;
 }
 
 static void pm_update_sci(PIIX4PMState *s)
 {
-    int sci_level, pmsts;
-    int64_t expire_time;
+    int sci_level;
 
-    pmsts = get_pmsts(s);
-    sci_level = (((pmsts & s->pmen) &
-                  (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0);
-    qemu_set_irq(s->irq, sci_level);
-    /* schedule a timer interruption if needed */
-    if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) {
-        expire_time = muldiv64(s->tmr_overflow_time, ticks_per_sec, PM_FREQ);
-        qemu_mod_timer(s->tmr_timer, expire_time);
-        s->tmr_overflow_time += 0x800000;
-    } else {
-        qemu_del_timer(s->tmr_timer);
-    }
+    sci_level = (((s->pmsts & s->pmen) & 
+                   (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0);
+    if (!sci_level)
+        qemu_set_irq(s->irq, sci_level);
 }
 
 static void pm_tmr_timer(void *opaque)
 {
     PIIX4PMState *s = opaque;
-    pm_update_sci(s);
+    update_pmtmr(s);
 }
 
 static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
@@ -123,18 +140,9 @@
     addr &= 0x3f;
     switch(addr) {
     case 0x00:
-        {
-            int64_t d;
-            int pmsts;
-            pmsts = get_pmsts(s);
-            if (pmsts & val & TMROF_EN) {
-                /* if TMRSTS is reset, then compute the new overflow time */
-                d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec);
-                s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
-            }
-            s->pmsts &= ~val;
-            pm_update_sci(s);
-        }
+        s->pmsts &= ~val;
+        update_pmtmr(s);
+        pm_update_sci(s);
         break;
     case 0x02:
         s->pmen = val;

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

* Re: [Qemu-devel] [4258] Fix sci irq set when acpi timer about to wrap (Dor Laor, Yaniv Kamay ).
  2008-04-26 14:50 [Qemu-devel] [4258] Fix sci irq set when acpi timer about to wrap (Dor Laor, Yaniv Kamay ) Andrzej Zaborowski
@ 2008-04-27 20:14 ` Avi Kivity
  2008-04-27 22:53   ` andrzej zaborowski
  0 siblings, 1 reply; 3+ messages in thread
From: Avi Kivity @ 2008-04-27 20:14 UTC (permalink / raw)
  To: balrogg; +Cc: qemu-devel

Andrzej Zaborowski wrote:
> Revision: 4258
>           http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4258
> Author:   balrog
> Date:     2008-04-26 14:50:48 +0000 (Sat, 26 Apr 2008)
>
> Log Message:
> -----------
> Fix sci irq set when acpi timer about to wrap (Dor Laor, Yaniv Kamay).
>
>   

I reverted this patch in kvm's copy of qemu, as it caused Linux to stop 
receiving scis, killing the system_powerdown functionality.

-- 
Any sufficiently difficult bug is indistinguishable from a feature.

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

* Re: [Qemu-devel] [4258] Fix sci irq set when acpi timer about to wrap (Dor Laor, Yaniv Kamay ).
  2008-04-27 20:14 ` Avi Kivity
@ 2008-04-27 22:53   ` andrzej zaborowski
  0 siblings, 0 replies; 3+ messages in thread
From: andrzej zaborowski @ 2008-04-27 22:53 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel

On 27/04/2008, Avi Kivity <avi@qumranet.com> wrote:
> Andrzej Zaborowski wrote:
>
> > Revision: 4258
> >
> http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4258
> > Author:   balrog
> > Date:     2008-04-26 14:50:48 +0000 (Sat, 26 Apr 2008)
> >
> > Log Message:
> > -----------
> > Fix sci irq set when acpi timer about to wrap (Dor Laor, Yaniv Kamay).
> >
> >
> >
>
>  I reverted this patch in kvm's copy of qemu, as it caused Linux to stop
> receiving scis, killing the system_powerdown functionality.

Ouch, I understood from
http://lists.gnu.org/archive/html/qemu-devel/2008-03/msg00318.html
that it was already in kvm.  I was unable to test system_powerdown but
I'll revert as well.

Cheers
-- 
Please do not print this email unless absolutely necessary. Spread
environmental awareness.

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

end of thread, other threads:[~2008-04-27 22:54 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-26 14:50 [Qemu-devel] [4258] Fix sci irq set when acpi timer about to wrap (Dor Laor, Yaniv Kamay ) Andrzej Zaborowski
2008-04-27 20:14 ` Avi Kivity
2008-04-27 22:53   ` andrzej zaborowski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).