Add PowerPC power-management state check callback.
[qemu] / hw / ptimer.c
index 2f350fc..d81503a 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * General purpose implementation of a simple periodic countdown timer.
  *
  * Copyright (c) 2007 CodeSourcery.
@@ -11,8 +11,8 @@
 struct ptimer_state
 {
     int enabled; /* 0 = disabled, 1 = periodic, 2 = oneshot.  */
-    uint32_t limit;
-    uint32_t delta;
+    uint64_t limit;
+    uint64_t delta;
     uint32_t period_frac;
     int64_t period;
     int64_t last_event;
@@ -61,10 +61,10 @@ static void ptimer_tick(void *opaque)
     }
 }
 
-uint32_t ptimer_get_count(ptimer_state *s)
+uint64_t ptimer_get_count(ptimer_state *s)
 {
     int64_t now;
-    uint32_t counter;
+    uint64_t counter;
 
     if (s->enabled) {
         now = qemu_get_clock(vm_clock);
@@ -75,8 +75,8 @@ uint32_t ptimer_get_count(ptimer_state *s)
                triggered.  */
             counter = 0;
         } else {
-            int64_t rem;
-            int64_t div;
+            uint64_t rem;
+            uint64_t div;
 
             rem = s->next_event - now;
             div = s->period;
@@ -88,7 +88,7 @@ uint32_t ptimer_get_count(ptimer_state *s)
     return counter;
 }
 
-void ptimer_set_count(ptimer_state *s, uint32_t count)
+void ptimer_set_count(ptimer_state *s, uint64_t count)
 {
     s->delta = count;
     if (s->enabled) {
@@ -108,7 +108,7 @@ void ptimer_run(ptimer_state *s, int oneshot)
     ptimer_reload(s);
 }
 
-/* Pause a timer.  Note that this may cause it to "loose" time, even if it
+/* Pause a timer.  Note that this may cause it to "lose" time, even if it
    is immediately restarted.  */
 void ptimer_stop(ptimer_state *s)
 {
@@ -123,33 +123,60 @@ void ptimer_stop(ptimer_state *s)
 /* Set counter increment interval in nanoseconds.  */
 void ptimer_set_period(ptimer_state *s, int64_t period)
 {
-    if (s->enabled) {
-        fprintf(stderr, "FIXME: ptimer_set_period with running timer");
-    }
     s->period = period;
     s->period_frac = 0;
+    if (s->enabled) {
+        s->next_event = qemu_get_clock(vm_clock);
+        ptimer_reload(s);
+    }
 }
 
 /* Set counter frequency in Hz.  */
 void ptimer_set_freq(ptimer_state *s, uint32_t freq)
 {
-    if (s->enabled) {
-        fprintf(stderr, "FIXME: ptimer_set_freq with running timer");
-    }
     s->period = 1000000000ll / freq;
     s->period_frac = (1000000000ll << 32) / freq;
+    if (s->enabled) {
+        s->next_event = qemu_get_clock(vm_clock);
+        ptimer_reload(s);
+    }
 }
 
 /* Set the initial countdown value.  If reload is nonzero then also set
    count = limit.  */
-void ptimer_set_limit(ptimer_state *s, uint32_t limit, int reload)
+void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
 {
-    if (s->enabled) {
-        fprintf(stderr, "FIXME: ptimer_set_limit with running timer");
-    }
     s->limit = limit;
     if (reload)
         s->delta = limit;
+    if (s->enabled && reload) {
+        s->next_event = qemu_get_clock(vm_clock);
+        ptimer_reload(s);
+    }
+}
+
+void qemu_put_ptimer(QEMUFile *f, ptimer_state *s)
+{
+    qemu_put_byte(f, s->enabled);
+    qemu_put_be64s(f, &s->limit);
+    qemu_put_be64s(f, &s->delta);
+    qemu_put_be32s(f, &s->period_frac);
+    qemu_put_be64s(f, &s->period);
+    qemu_put_be64s(f, &s->last_event);
+    qemu_put_be64s(f, &s->next_event);
+    qemu_put_timer(f, s->timer);
+}
+
+void qemu_get_ptimer(QEMUFile *f, ptimer_state *s)
+{
+    s->enabled = qemu_get_byte(f);
+    qemu_get_be64s(f, &s->limit);
+    qemu_get_be64s(f, &s->delta);
+    qemu_get_be32s(f, &s->period_frac);
+    qemu_get_be64s(f, &s->period);
+    qemu_get_be64s(f, &s->last_event);
+    qemu_get_be64s(f, &s->next_event);
+    qemu_get_timer(f, s->timer);
 }
 
 ptimer_state *ptimer_init(QEMUBH *bh)