Commit aec454d23a5f0271e1c4f490dabe2a18fbe98f36
1 parent
7e7c5e4c
Use qemu time/date functions for the Menelaus RTC.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4216 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
14 additions
and
17 deletions
hw/twl92230.c
| @@ -59,9 +59,9 @@ struct menelaus_s { | @@ -59,9 +59,9 @@ struct menelaus_s { | ||
| 59 | struct tm tm; | 59 | struct tm tm; |
| 60 | struct tm new; | 60 | struct tm new; |
| 61 | struct tm alm; | 61 | struct tm alm; |
| 62 | - time_t sec; | ||
| 63 | - time_t alm_sec; | ||
| 64 | - time_t next_comp; | 62 | + int sec_offset; |
| 63 | + int alm_sec; | ||
| 64 | + int next_comp; | ||
| 65 | struct tm *(*gettime)(const time_t *timep, struct tm *result); | 65 | struct tm *(*gettime)(const time_t *timep, struct tm *result); |
| 66 | } rtc; | 66 | } rtc; |
| 67 | qemu_irq handler[3]; | 67 | qemu_irq handler[3]; |
| @@ -91,20 +91,21 @@ static inline void menelaus_rtc_stop(struct menelaus_s *s) | @@ -91,20 +91,21 @@ static inline void menelaus_rtc_stop(struct menelaus_s *s) | ||
| 91 | 91 | ||
| 92 | static void menelaus_rtc_update(struct menelaus_s *s) | 92 | static void menelaus_rtc_update(struct menelaus_s *s) |
| 93 | { | 93 | { |
| 94 | - s->rtc.gettime(&s->rtc.sec, &s->rtc.tm); | 94 | + qemu_get_timedate(&s->rtc.tm, s->rtc.sec_offset); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | static void menelaus_alm_update(struct menelaus_s *s) | 97 | static void menelaus_alm_update(struct menelaus_s *s) |
| 98 | { | 98 | { |
| 99 | if ((s->rtc.ctrl & 3) == 3) | 99 | if ((s->rtc.ctrl & 3) == 3) |
| 100 | - s->rtc.alm_sec = mktime(&s->rtc.alm); | 100 | + s->rtc.alm_sec = qemu_timedate_diff(&s->rtc.alm) - s->rtc.sec_offset; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | static void menelaus_rtc_hz(void *opaque) | 103 | static void menelaus_rtc_hz(void *opaque) |
| 104 | { | 104 | { |
| 105 | struct menelaus_s *s = (struct menelaus_s *) opaque; | 105 | struct menelaus_s *s = (struct menelaus_s *) opaque; |
| 106 | 106 | ||
| 107 | - s->rtc.sec ++; | 107 | + s->rtc.next_comp --; |
| 108 | + s->rtc.alm_sec --; | ||
| 108 | s->rtc.next += 1000; | 109 | s->rtc.next += 1000; |
| 109 | qemu_mod_timer(s->rtc.hz, s->rtc.next); | 110 | qemu_mod_timer(s->rtc.hz, s->rtc.next); |
| 110 | if ((s->rtc.ctrl >> 3) & 3) { /* EVERY */ | 111 | if ((s->rtc.ctrl >> 3) & 3) { /* EVERY */ |
| @@ -118,13 +119,13 @@ static void menelaus_rtc_hz(void *opaque) | @@ -118,13 +119,13 @@ static void menelaus_rtc_hz(void *opaque) | ||
| 118 | } else | 119 | } else |
| 119 | s->status |= 1 << 8; /* RTCTMR */ | 120 | s->status |= 1 << 8; /* RTCTMR */ |
| 120 | if ((s->rtc.ctrl >> 1) & 1) { /* RTC_AL_EN */ | 121 | if ((s->rtc.ctrl >> 1) & 1) { /* RTC_AL_EN */ |
| 121 | - if (s->rtc.sec == s->rtc.alm_sec) | 122 | + if (s->rtc.alm_sec == 0) |
| 122 | s->status |= 1 << 9; /* RTCALM */ | 123 | s->status |= 1 << 9; /* RTCALM */ |
| 123 | /* TODO: wake-up */ | 124 | /* TODO: wake-up */ |
| 124 | } | 125 | } |
| 125 | - if (s->rtc.next_comp >= s->rtc.sec) { | 126 | + if (s->rtc.next_comp <= 0) { |
| 126 | s->rtc.next -= muldiv64((int16_t) s->rtc.comp, 1000, 0x8000); | 127 | s->rtc.next -= muldiv64((int16_t) s->rtc.comp, 1000, 0x8000); |
| 127 | - s->rtc.next_comp = s->rtc.sec + 3600; | 128 | + s->rtc.next_comp = 3600; |
| 128 | } | 129 | } |
| 129 | menelaus_update(s); | 130 | menelaus_update(s); |
| 130 | } | 131 | } |
| @@ -132,7 +133,6 @@ static void menelaus_rtc_hz(void *opaque) | @@ -132,7 +133,6 @@ static void menelaus_rtc_hz(void *opaque) | ||
| 132 | void menelaus_reset(i2c_slave *i2c) | 133 | void menelaus_reset(i2c_slave *i2c) |
| 133 | { | 134 | { |
| 134 | struct menelaus_s *s = (struct menelaus_s *) i2c; | 135 | struct menelaus_s *s = (struct menelaus_s *) i2c; |
| 135 | - time_t ti; | ||
| 136 | s->reg = 0x00; | 136 | s->reg = 0x00; |
| 137 | 137 | ||
| 138 | s->vcore[0] = 0x0c; /* XXX: X-loader needs 0x8c? check! */ | 138 | s->vcore[0] = 0x0c; /* XXX: X-loader needs 0x8c? check! */ |
| @@ -169,14 +169,14 @@ void menelaus_reset(i2c_slave *i2c) | @@ -169,14 +169,14 @@ void menelaus_reset(i2c_slave *i2c) | ||
| 169 | s->mmc_ctrl[2] = 0x00; | 169 | s->mmc_ctrl[2] = 0x00; |
| 170 | s->mmc_debounce = 0x05; | 170 | s->mmc_debounce = 0x05; |
| 171 | 171 | ||
| 172 | - time(&ti); | ||
| 173 | if (s->rtc.ctrl & 1) | 172 | if (s->rtc.ctrl & 1) |
| 174 | menelaus_rtc_stop(s); | 173 | menelaus_rtc_stop(s); |
| 175 | s->rtc.ctrl = 0x00; | 174 | s->rtc.ctrl = 0x00; |
| 176 | s->rtc.comp = 0x0000; | 175 | s->rtc.comp = 0x0000; |
| 177 | s->rtc.next = 1000; | 176 | s->rtc.next = 1000; |
| 178 | - s->rtc.sec = ti; | ||
| 179 | - s->rtc.next_comp = s->rtc.sec + 1800; | 177 | + s->rtc.sec_offset = 0; |
| 178 | + s->rtc.next_comp = 1800; | ||
| 179 | + s->rtc.alm_sec = 1800; | ||
| 180 | s->rtc.alm.tm_sec = 0x00; | 180 | s->rtc.alm.tm_sec = 0x00; |
| 181 | s->rtc.alm.tm_min = 0x00; | 181 | s->rtc.alm.tm_min = 0x00; |
| 182 | s->rtc.alm.tm_hour = 0x00; | 182 | s->rtc.alm.tm_hour = 0x00; |
| @@ -627,7 +627,7 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value) | @@ -627,7 +627,7 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value) | ||
| 627 | s->status |= 1 << 10; /* RTCERR */ | 627 | s->status |= 1 << 10; /* RTCERR */ |
| 628 | menelaus_update(s); | 628 | menelaus_update(s); |
| 629 | } | 629 | } |
| 630 | - s->rtc.sec += difftime(mktime(&tm), mktime(&s->rtc.tm)); | 630 | + s->rtc.sec_offset = qemu_timedate_diff(&tm); |
| 631 | break; | 631 | break; |
| 632 | case MENELAUS_RTC_SEC: | 632 | case MENELAUS_RTC_SEC: |
| 633 | s->rtc.tm.tm_sec = from_bcd(value & 0x7f); | 633 | s->rtc.tm.tm_sec = from_bcd(value & 0x7f); |
| @@ -888,9 +888,6 @@ i2c_slave *twl92230_init(i2c_bus *bus, qemu_irq irq) | @@ -888,9 +888,6 @@ i2c_slave *twl92230_init(i2c_bus *bus, qemu_irq irq) | ||
| 888 | s->i2c.recv = menelaus_rx; | 888 | s->i2c.recv = menelaus_rx; |
| 889 | s->i2c.send = menelaus_tx; | 889 | s->i2c.send = menelaus_tx; |
| 890 | 890 | ||
| 891 | - /* TODO: use the qemu gettime functions */ | ||
| 892 | - s->rtc.gettime = localtime_r; | ||
| 893 | - | ||
| 894 | s->irq = irq; | 891 | s->irq = irq; |
| 895 | s->rtc.hz = qemu_new_timer(rt_clock, menelaus_rtc_hz, s); | 892 | s->rtc.hz = qemu_new_timer(rt_clock, menelaus_rtc_hz, s); |
| 896 | s->in = qemu_allocate_irqs(menelaus_gpio_set, s, 3); | 893 | s->in = qemu_allocate_irqs(menelaus_gpio_set, s, 3); |