aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/m48t59.c122
-rw-r--r--hw/mc146818rtc.c18
-rw-r--r--hw/omap.c10
-rw-r--r--hw/pl031.c11
-rw-r--r--hw/pxa2xx.c27
5 files changed, 70 insertions, 118 deletions
diff --git a/hw/m48t59.c b/hw/m48t59.c
index 45c05a0ed4..b781f50bf9 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -53,7 +53,7 @@ struct m48t59_t {
time_t time_offset;
time_t stop_time;
/* Alarm & watchdog */
- time_t alarm;
+ struct tm alarm;
struct QEMUTimer *alrm_timer;
struct QEMUTimer *wd_timer;
/* NVRAM storage */
@@ -74,35 +74,10 @@ static inline uint8_t fromBCD (uint8_t BCD)
return ((BCD >> 4) * 10) + (BCD & 0x0F);
}
-/* RTC management helpers */
-static void get_time (m48t59_t *NVRAM, struct tm *tm)
-{
- time_t t;
-
- t = time(NULL) + NVRAM->time_offset;
-#ifdef _WIN32
- memcpy(tm,localtime(&t),sizeof(*tm));
-#else
- if (rtc_utc)
- gmtime_r (&t, tm);
- else
- localtime_r (&t, tm) ;
-#endif
-}
-
-static void set_time (m48t59_t *NVRAM, struct tm *tm)
-{
- time_t now, new_time;
-
- new_time = mktime(tm);
- now = time(NULL);
- NVRAM->time_offset = new_time - now;
-}
-
/* Alarm management */
static void alarm_cb (void *opaque)
{
- struct tm tm, tm_now;
+ struct tm tm;
uint64_t next_time;
m48t59_t *NVRAM = opaque;
@@ -111,62 +86,62 @@ static void alarm_cb (void *opaque)
(NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
- /* Repeat once a month */
- get_time(NVRAM, &tm_now);
- memcpy(&tm, &tm_now, sizeof(struct tm));
- tm.tm_mon++;
- if (tm.tm_mon == 13) {
- tm.tm_mon = 1;
- tm.tm_year++;
- }
- next_time = mktime(&tm);
+ /* Repeat once a month */
+ qemu_get_timedate(&tm, NVRAM->time_offset);
+ tm.tm_mon++;
+ if (tm.tm_mon == 13) {
+ tm.tm_mon = 1;
+ tm.tm_year++;
+ }
+ next_time = qemu_timedate_diff(&tm) - NVRAM->time_offset;
} else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
- /* Repeat once a day */
- next_time = 24 * 60 * 60 + mktime(&tm_now);
+ /* Repeat once a day */
+ next_time = 24 * 60 * 60;
} else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
- /* Repeat once an hour */
- next_time = 60 * 60 + mktime(&tm_now);
+ /* Repeat once an hour */
+ next_time = 60 * 60;
} else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
- /* Repeat once a minute */
- next_time = 60 + mktime(&tm_now);
+ /* Repeat once a minute */
+ next_time = 60;
} else {
- /* Repeat once a second */
- next_time = 1 + mktime(&tm_now);
+ /* Repeat once a second */
+ next_time = 1;
}
- qemu_mod_timer(NVRAM->alrm_timer, next_time * 1000);
+ qemu_mod_timer(NVRAM->alrm_timer, qemu_get_clock(vm_clock) +
+ next_time * 1000);
qemu_set_irq(NVRAM->IRQ, 0);
}
+static void set_alarm (m48t59_t *NVRAM)
+{
+ int diff;
+ if (NVRAM->alrm_timer != NULL) {
+ qemu_del_timer(NVRAM->alrm_timer);
+ diff = qemu_timedate_diff(&NVRAM->alarm) - NVRAM->time_offset;
+ if (diff > 0)
+ qemu_mod_timer(NVRAM->alrm_timer, diff * 1000);
+ }
+}
-static void get_alarm (m48t59_t *NVRAM, struct tm *tm)
+/* RTC management helpers */
+static inline void get_time (m48t59_t *NVRAM, struct tm *tm)
{
-#ifdef _WIN32
- memcpy(tm,localtime(&NVRAM->alarm),sizeof(*tm));
-#else
- if (rtc_utc)
- gmtime_r (&NVRAM->alarm, tm);
- else
- localtime_r (&NVRAM->alarm, tm);
-#endif
+ qemu_get_timedate(tm, NVRAM->time_offset);
}
-static void set_alarm (m48t59_t *NVRAM, struct tm *tm)
+static void set_time (m48t59_t *NVRAM, struct tm *tm)
{
- NVRAM->alarm = mktime(tm);
- if (NVRAM->alrm_timer != NULL) {
- qemu_del_timer(NVRAM->alrm_timer);
- if (NVRAM->alarm - time(NULL) > 0)
- qemu_mod_timer(NVRAM->alrm_timer, NVRAM->alarm * 1000);
- }
+ NVRAM->time_offset = qemu_timedate_diff(tm);
+ set_alarm(NVRAM);
}
/* Watchdog management */
@@ -229,40 +204,36 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
/* alarm seconds */
tmp = fromBCD(val & 0x7F);
if (tmp >= 0 && tmp <= 59) {
- get_alarm(NVRAM, &tm);
- tm.tm_sec = tmp;
+ NVRAM->alarm.tm_sec = tmp;
NVRAM->buffer[0x1FF2] = val;
- set_alarm(NVRAM, &tm);
+ set_alarm(NVRAM);
}
break;
case 0x1FF3:
/* alarm minutes */
tmp = fromBCD(val & 0x7F);
if (tmp >= 0 && tmp <= 59) {
- get_alarm(NVRAM, &tm);
- tm.tm_min = tmp;
+ NVRAM->alarm.tm_min = tmp;
NVRAM->buffer[0x1FF3] = val;
- set_alarm(NVRAM, &tm);
+ set_alarm(NVRAM);
}
break;
case 0x1FF4:
/* alarm hours */
tmp = fromBCD(val & 0x3F);
if (tmp >= 0 && tmp <= 23) {
- get_alarm(NVRAM, &tm);
- tm.tm_hour = tmp;
+ NVRAM->alarm.tm_hour = tmp;
NVRAM->buffer[0x1FF4] = val;
- set_alarm(NVRAM, &tm);
+ set_alarm(NVRAM);
}
break;
case 0x1FF5:
/* alarm date */
tmp = fromBCD(val & 0x1F);
if (tmp != 0) {
- get_alarm(NVRAM, &tm);
- tm.tm_mday = tmp;
+ NVRAM->alarm.tm_mday = tmp;
NVRAM->buffer[0x1FF5] = val;
- set_alarm(NVRAM, &tm);
+ set_alarm(NVRAM);
}
break;
case 0x1FF6:
@@ -288,7 +259,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
tm.tm_sec = tmp;
set_time(NVRAM, &tm);
}
- if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) {
+ if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) {
if (val & 0x80) {
NVRAM->stop_time = time(NULL);
} else {
@@ -296,7 +267,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
NVRAM->stop_time = 0;
}
}
- NVRAM->buffer[addr] = val & 0x80;
+ NVRAM->buffer[addr] = val & 0x80;
break;
case 0x1FFA:
case 0x07FA:
@@ -682,6 +653,7 @@ m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base,
s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);
}
s->lock = 0;
+ qemu_get_timedate(&s->alarm, 0);
qemu_register_reset(m48t59_reset, s);
save_base = mem_base ? mem_base : io_base;
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index e1e6427687..30bb0449da 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -392,24 +392,14 @@ void rtc_set_date(RTCState *s, const struct tm *tm)
static void rtc_set_date_from_host(RTCState *s)
{
- time_t ti;
- struct tm *tm;
+ struct tm tm;
int val;
/* set the CMOS date */
- if (rtc_start_date == -1) {
- time(&ti);
- if (rtc_utc)
- tm = gmtime(&ti);
- else
- tm = localtime(&ti);
- } else {
- ti = rtc_start_date;
- tm = gmtime(&ti);
- }
- rtc_set_date(s, tm);
+ qemu_get_timedate(&tm, 0);
+ rtc_set_date(s, &tm);
- val = to_bcd(s, (tm->tm_year / 100) + 19);
+ val = to_bcd(s, (tm.tm_year / 100) + 19);
rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
}
diff --git a/hw/omap.c b/hw/omap.c
index ce63597f15..ee426dc0d1 100644
--- a/hw/omap.c
+++ b/hw/omap.c
@@ -4345,7 +4345,6 @@ struct omap_rtc_s {
int pm_am;
int auto_comp;
int round;
- struct tm *(*convert)(const time_t *timep, struct tm *result);
struct tm alarm_tm;
time_t alarm_ti;
@@ -4668,7 +4667,7 @@ static void omap_rtc_tick(void *opaque)
s->round = 0;
}
- localtime_r(&s->ti, &s->current_tm);
+ memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
s->status |= 0x40;
@@ -4719,6 +4718,8 @@ static void omap_rtc_tick(void *opaque)
static void omap_rtc_reset(struct omap_rtc_s *s)
{
+ struct tm tm;
+
s->interrupts = 0;
s->comp_reg = 0;
s->running = 0;
@@ -4729,8 +4730,8 @@ static void omap_rtc_reset(struct omap_rtc_s *s)
memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
s->alarm_tm.tm_mday = 0x01;
s->status = 1 << 7;
- time(&s->ti);
- s->ti = mktime(s->convert(&s->ti, &s->current_tm));
+ qemu_get_timedate(&tm, 0);
+ s->ti = mktime(&tm);
omap_rtc_alarm_update(s);
omap_rtc_tick(s);
@@ -4747,7 +4748,6 @@ struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
s->irq = irq[0];
s->alarm = irq[1];
s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
- s->convert = rtc_utc ? gmtime_r : localtime_r;
omap_rtc_reset(s);
diff --git a/hw/pl031.c b/hw/pl031.c
index 68e9005c0e..bb5a69d039 100644
--- a/hw/pl031.c
+++ b/hw/pl031.c
@@ -195,8 +195,7 @@ void pl031_init(uint32_t base, qemu_irq irq)
{
int iomemtype;
pl031_state *s;
- time_t ti;
- struct tm *tm;
+ struct tm tm;
s = qemu_mallocz(sizeof(pl031_state));
if (!s)
@@ -211,12 +210,8 @@ void pl031_init(uint32_t base, qemu_irq irq)
s->base = base;
s->irq = irq;
/* ??? We assume vm_clock is zero at this point. */
- time(&ti);
- if (rtc_utc)
- tm = gmtime(&ti);
- else
- tm = localtime(&ti);
- s->tick_offset = mktime(tm);
+ qemu_get_timedate(&tm, 0);
+ s->tick_offset = mktime(&tm);
s->timer = qemu_new_timer(vm_clock, pl031_interrupt, s);
}
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 14e3b9573e..0cb16725af 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1183,27 +1183,22 @@ static CPUWriteMemoryFunc *pxa2xx_rtc_writefn[] = {
static void pxa2xx_rtc_init(struct pxa2xx_state_s *s)
{
- struct tm *tm;
- time_t ti;
+ struct tm tm;
int wom;
s->rttr = 0x7fff;
s->rtsr = 0;
- time(&ti);
- if (rtc_utc)
- tm = gmtime(&ti);
- else
- tm = localtime(&ti);
- wom = ((tm->tm_mday - 1) / 7) + 1;
-
- s->last_rcnr = (uint32_t) ti;
- s->last_rdcr = (wom << 20) | ((tm->tm_wday + 1) << 17) |
- (tm->tm_hour << 12) | (tm->tm_min << 6) | tm->tm_sec;
- s->last_rycr = ((tm->tm_year + 1900) << 9) |
- ((tm->tm_mon + 1) << 5) | tm->tm_mday;
- s->last_swcr = (tm->tm_hour << 19) |
- (tm->tm_min << 13) | (tm->tm_sec << 7);
+ qemu_get_timedate(&tm, 0);
+ wom = ((tm.tm_mday - 1) / 7) + 1;
+
+ s->last_rcnr = (uint32_t) mktime(&tm);
+ s->last_rdcr = (wom << 20) | ((tm.tm_wday + 1) << 17) |
+ (tm.tm_hour << 12) | (tm.tm_min << 6) | tm.tm_sec;
+ s->last_rycr = ((tm.tm_year + 1900) << 9) |
+ ((tm.tm_mon + 1) << 5) | tm.tm_mday;
+ s->last_swcr = (tm.tm_hour << 19) |
+ (tm.tm_min << 13) | (tm.tm_sec << 7);
s->last_rtcpicr = 0;
s->last_hz = s->last_sw = s->last_pi = qemu_get_clock(rt_clock);