diff options
author | Antoine Mathys <barsamin@gmail.com> | 2012-12-13 14:05:28 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2012-12-13 14:05:28 +0000 |
commit | 871edc5fdba884929102b89d28ff363c94f0822d (patch) | |
tree | 50637821edbac09b3fc02cf1ffb3f99a4554f70c /hw | |
parent | 996e91f04b9cc55cf246052856abe9189a5a0f28 (diff) | |
download | qemu-871edc5fdba884929102b89d28ff363c94f0822d.zip qemu-871edc5fdba884929102b89d28ff363c94f0822d.tar.gz qemu-871edc5fdba884929102b89d28ff363c94f0822d.tar.bz2 |
hw/ds1338.c: Fix handling of DAY (wday) register.
Per the datasheet, the DAY (wday) register is user defined. Implement this.
Signed-off-by: Antoine Mathys <barsamin@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ds1338.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/hw/ds1338.c b/hw/ds1338.c index 94a2f54..1aefa3b 100644 --- a/hw/ds1338.c +++ b/hw/ds1338.c @@ -26,6 +26,7 @@ typedef struct { I2CSlave i2c; int64_t offset; + uint8_t wday_offset; uint8_t nvram[NVRAM_SIZE]; int32_t ptr; bool addr_byte; @@ -33,12 +34,13 @@ typedef struct { static const VMStateDescription vmstate_ds1338 = { .name = "ds1338", - .version_id = 1, + .version_id = 2, .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField[]) { VMSTATE_I2C_SLAVE(i2c, DS1338State), VMSTATE_INT64(offset, DS1338State), + VMSTATE_UINT8_V(wday_offset, DS1338State, 2), VMSTATE_UINT8_ARRAY(nvram, DS1338State, NVRAM_SIZE), VMSTATE_INT32(ptr, DS1338State), VMSTATE_BOOL(addr_byte, DS1338State), @@ -68,7 +70,7 @@ static void capture_current_time(DS1338State *s) } else { s->nvram[2] = to_bcd(now.tm_hour); } - s->nvram[3] = to_bcd(now.tm_wday + 1); + s->nvram[3] = (now.tm_wday + s->wday_offset) % 7 + 1; s->nvram[4] = to_bcd(now.tm_mday); s->nvram[5] = to_bcd(now.tm_mon + 1); s->nvram[6] = to_bcd(now.tm_year - 100); @@ -152,7 +154,13 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data) } break; case 3: - now.tm_wday = from_bcd(data & 7) - 1; + { + /* The day field is supposed to contain a value in + the range 1-7. Otherwise behavior is undefined. + */ + int user_wday = (data & 7) - 1; + s->wday_offset = (user_wday - now.tm_wday + 7) % 7; + } break; case 4: now.tm_mday = from_bcd(data & 0x3f); @@ -194,6 +202,7 @@ static void ds1338_reset(DeviceState *dev) /* The clock is running and synchronized with the host */ s->offset = 0; + s->wday_offset = 0; memset(s->nvram, 0, NVRAM_SIZE); s->ptr = 0; s->addr_byte = false; |