Patchwork [v3,4/6] hw/ds1338.c: Ensure state is properly initialized.

login
register
mail settings
Submitter Antoine Mathys
Date Dec. 12, 2012, 10:35 p.m.
Message ID <50C906BF.2030806@gmail.com>
Download mbox | patch
Permalink /patch/205675/
State New
Headers show

Comments

Antoine Mathys - Dec. 12, 2012, 10:35 p.m.
Signed-off-by: Antoine Mathys <barsamin@gmail.com>
---
  hw/ds1338.c |   51 ++++++++++++++++++++++++++++++++++++++-------------
  1 file changed, 38 insertions(+), 13 deletions(-)
Antoine Mathys - Dec. 12, 2012, 10:40 p.m.
Oops. There was a problem in the patch. Resending the series.

Patch

diff --git a/hw/ds1338.c b/hw/ds1338.c
index b576d56..d2f52fc 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -17,6 +17,12 @@ 
   */
  #define NVRAM_SIZE 64

+/* Flags definitions */
+#define SECONDS_CH 0x80
+#define HOURS_12   0x40
+#define HOURS_PM   0x20
+#define CTRL_OSF   0x20
+
  typedef struct {
      I2CSlave i2c;
      int64_t offset;
@@ -49,17 +55,22 @@  static void capture_current_time(DS1338State *s)
      qemu_get_timedate(&now, s->offset);
      s->nvram[0] = to_bcd(now.tm_sec);
      s->nvram[1] = to_bcd(now.tm_min);
-    if (s->nvram[2] & 0x40) {
-        s->nvram[2] = (to_bcd((now.tm_hour % 12)) + 1) | 0x40;
-        if (now.tm_hour >= 12) {
-            s->nvram[2] |= 0x20;
+    if (s->nvram[2] & HOURS_12) {
+        int tmp = now.tm_hour;
+        if (tmp == 0) {
+            tmp = 24;
+        }
+        if (tmp <= 12) {
+            s->nvram[2] = HOURS_12 | to_bcd(tmp);
+        } else {
+            s->nvram[2] = HOURS_12 | HOURS_PM | to_bcd(tmp - 12);
          }
      } else {
          s->nvram[2] = to_bcd(now.tm_hour);
      }
-    s->nvram[3] = to_bcd(now.tm_wday) + 1;
+    s->nvram[3] = to_bcd(now.tm_wday + 1);
      s->nvram[4] = to_bcd(now.tm_mday);
-    s->nvram[5] = to_bcd(now.tm_mon) + 1;
+    s->nvram[5] = to_bcd(now.tm_mon + 1);
      s->nvram[6] = to_bcd(now.tm_year - 100);
  }

@@ -126,16 +137,18 @@  static int ds1338_send(I2CSlave *i2c, uint8_t data)
              now.tm_min = from_bcd(data & 0x7f);
              break;
          case 2:
-            if (data & 0x40) {
-                if (data & 0x20) {
-                    data = from_bcd(data & 0x4f) + 11;
-                } else {
-                    data = from_bcd(data & 0x1f) - 1;
+            if (data & HOURS_12) {
+                int tmp = from_bcd(data & (HOURS_PM - 1));
+                if (data & HOURS_PM) {
+                    tmp += 12;
                  }
+                if (tmp == 24) {
+                    tmp = 0;
+                }
+                now.tm_hour = tmp;
              } else {
-                data = from_bcd(data);
+                now.tm_hour = from_bcd(data & (HOURS_12 - 1));
              }
-            now.tm_hour = data;
              break;
          case 3:
              now.tm_wday = from_bcd(data & 7) - 1;
@@ -166,6 +179,17 @@  static int ds1338_init(I2CSlave *i2c)
      return 0;
  }

+static void ds1338_reset(DeviceState *dev)
+{
+    DS1338State *s = FROM_I2C_SLAVE(DS1338State, I2C_SLAVE_FROM_QDEV(dev));
+
+    /* The clock is running and synchronized with the host */
+    s->offset = 0;
+    memset(s->nvram, 0, NVRAM_SIZE);
+    s->ptr = 0;
+    s->addr_byte = false;
+}
+
  static void ds1338_class_init(ObjectClass *klass, void *data)
  {
      DeviceClass *dc = DEVICE_CLASS(klass);
@@ -175,6 +199,7 @@  static void ds1338_class_init(ObjectClass *klass, 
void *data)
      k->event = ds1338_event;
      k->recv = ds1338_recv;
      k->send = ds1338_send;
+    dc->reset = ds1338_reset;
      dc->vmsd = &vmstate_ds1338;
  }