Commit f650305967f3e9a2fe96f59de3062fd9e8b189d0

Authored by balrog
1 parent a0d69e00

Unify RTCs that use host time, fix M48t59 alarm.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3984 c046a42c-6fe2-441c-8c8c-71466251a162
hw/m48t59.c
@@ -53,7 +53,7 @@ struct m48t59_t { @@ -53,7 +53,7 @@ struct m48t59_t {
53 time_t time_offset; 53 time_t time_offset;
54 time_t stop_time; 54 time_t stop_time;
55 /* Alarm & watchdog */ 55 /* Alarm & watchdog */
56 - time_t alarm; 56 + struct tm alarm;
57 struct QEMUTimer *alrm_timer; 57 struct QEMUTimer *alrm_timer;
58 struct QEMUTimer *wd_timer; 58 struct QEMUTimer *wd_timer;
59 /* NVRAM storage */ 59 /* NVRAM storage */
@@ -74,35 +74,10 @@ static inline uint8_t fromBCD (uint8_t BCD) @@ -74,35 +74,10 @@ static inline uint8_t fromBCD (uint8_t BCD)
74 return ((BCD >> 4) * 10) + (BCD & 0x0F); 74 return ((BCD >> 4) * 10) + (BCD & 0x0F);
75 } 75 }
76 76
77 -/* RTC management helpers */  
78 -static void get_time (m48t59_t *NVRAM, struct tm *tm)  
79 -{  
80 - time_t t;  
81 -  
82 - t = time(NULL) + NVRAM->time_offset;  
83 -#ifdef _WIN32  
84 - memcpy(tm,localtime(&t),sizeof(*tm));  
85 -#else  
86 - if (rtc_utc)  
87 - gmtime_r (&t, tm);  
88 - else  
89 - localtime_r (&t, tm) ;  
90 -#endif  
91 -}  
92 -  
93 -static void set_time (m48t59_t *NVRAM, struct tm *tm)  
94 -{  
95 - time_t now, new_time;  
96 -  
97 - new_time = mktime(tm);  
98 - now = time(NULL);  
99 - NVRAM->time_offset = new_time - now;  
100 -}  
101 -  
102 /* Alarm management */ 77 /* Alarm management */
103 static void alarm_cb (void *opaque) 78 static void alarm_cb (void *opaque)
104 { 79 {
105 - struct tm tm, tm_now; 80 + struct tm tm;
106 uint64_t next_time; 81 uint64_t next_time;
107 m48t59_t *NVRAM = opaque; 82 m48t59_t *NVRAM = opaque;
108 83
@@ -111,62 +86,62 @@ static void alarm_cb (void *opaque) @@ -111,62 +86,62 @@ static void alarm_cb (void *opaque)
111 (NVRAM->buffer[0x1FF4] & 0x80) == 0 && 86 (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
112 (NVRAM->buffer[0x1FF3] & 0x80) == 0 && 87 (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
113 (NVRAM->buffer[0x1FF2] & 0x80) == 0) { 88 (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
114 - /* Repeat once a month */  
115 - get_time(NVRAM, &tm_now);  
116 - memcpy(&tm, &tm_now, sizeof(struct tm));  
117 - tm.tm_mon++;  
118 - if (tm.tm_mon == 13) {  
119 - tm.tm_mon = 1;  
120 - tm.tm_year++;  
121 - }  
122 - next_time = mktime(&tm); 89 + /* Repeat once a month */
  90 + qemu_get_timedate(&tm, NVRAM->time_offset);
  91 + tm.tm_mon++;
  92 + if (tm.tm_mon == 13) {
  93 + tm.tm_mon = 1;
  94 + tm.tm_year++;
  95 + }
  96 + next_time = qemu_timedate_diff(&tm) - NVRAM->time_offset;
123 } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 && 97 } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
124 (NVRAM->buffer[0x1FF4] & 0x80) == 0 && 98 (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
125 (NVRAM->buffer[0x1FF3] & 0x80) == 0 && 99 (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
126 (NVRAM->buffer[0x1FF2] & 0x80) == 0) { 100 (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
127 - /* Repeat once a day */  
128 - next_time = 24 * 60 * 60 + mktime(&tm_now); 101 + /* Repeat once a day */
  102 + next_time = 24 * 60 * 60;
129 } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 && 103 } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
130 (NVRAM->buffer[0x1FF4] & 0x80) != 0 && 104 (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
131 (NVRAM->buffer[0x1FF3] & 0x80) == 0 && 105 (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
132 (NVRAM->buffer[0x1FF2] & 0x80) == 0) { 106 (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
133 - /* Repeat once an hour */  
134 - next_time = 60 * 60 + mktime(&tm_now); 107 + /* Repeat once an hour */
  108 + next_time = 60 * 60;
135 } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 && 109 } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
136 (NVRAM->buffer[0x1FF4] & 0x80) != 0 && 110 (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
137 (NVRAM->buffer[0x1FF3] & 0x80) != 0 && 111 (NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
138 (NVRAM->buffer[0x1FF2] & 0x80) == 0) { 112 (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
139 - /* Repeat once a minute */  
140 - next_time = 60 + mktime(&tm_now); 113 + /* Repeat once a minute */
  114 + next_time = 60;
141 } else { 115 } else {
142 - /* Repeat once a second */  
143 - next_time = 1 + mktime(&tm_now); 116 + /* Repeat once a second */
  117 + next_time = 1;
144 } 118 }
145 - qemu_mod_timer(NVRAM->alrm_timer, next_time * 1000); 119 + qemu_mod_timer(NVRAM->alrm_timer, qemu_get_clock(vm_clock) +
  120 + next_time * 1000);
146 qemu_set_irq(NVRAM->IRQ, 0); 121 qemu_set_irq(NVRAM->IRQ, 0);
147 } 122 }
148 123
  124 +static void set_alarm (m48t59_t *NVRAM)
  125 +{
  126 + int diff;
  127 + if (NVRAM->alrm_timer != NULL) {
  128 + qemu_del_timer(NVRAM->alrm_timer);
  129 + diff = qemu_timedate_diff(&NVRAM->alarm) - NVRAM->time_offset;
  130 + if (diff > 0)
  131 + qemu_mod_timer(NVRAM->alrm_timer, diff * 1000);
  132 + }
  133 +}
149 134
150 -static void get_alarm (m48t59_t *NVRAM, struct tm *tm) 135 +/* RTC management helpers */
  136 +static inline void get_time (m48t59_t *NVRAM, struct tm *tm)
151 { 137 {
152 -#ifdef _WIN32  
153 - memcpy(tm,localtime(&NVRAM->alarm),sizeof(*tm));  
154 -#else  
155 - if (rtc_utc)  
156 - gmtime_r (&NVRAM->alarm, tm);  
157 - else  
158 - localtime_r (&NVRAM->alarm, tm);  
159 -#endif 138 + qemu_get_timedate(tm, NVRAM->time_offset);
160 } 139 }
161 140
162 -static void set_alarm (m48t59_t *NVRAM, struct tm *tm) 141 +static void set_time (m48t59_t *NVRAM, struct tm *tm)
163 { 142 {
164 - NVRAM->alarm = mktime(tm);  
165 - if (NVRAM->alrm_timer != NULL) {  
166 - qemu_del_timer(NVRAM->alrm_timer);  
167 - if (NVRAM->alarm - time(NULL) > 0)  
168 - qemu_mod_timer(NVRAM->alrm_timer, NVRAM->alarm * 1000);  
169 - } 143 + NVRAM->time_offset = qemu_timedate_diff(tm);
  144 + set_alarm(NVRAM);
170 } 145 }
171 146
172 /* Watchdog management */ 147 /* Watchdog management */
@@ -229,40 +204,36 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) @@ -229,40 +204,36 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
229 /* alarm seconds */ 204 /* alarm seconds */
230 tmp = fromBCD(val & 0x7F); 205 tmp = fromBCD(val & 0x7F);
231 if (tmp >= 0 && tmp <= 59) { 206 if (tmp >= 0 && tmp <= 59) {
232 - get_alarm(NVRAM, &tm);  
233 - tm.tm_sec = tmp; 207 + NVRAM->alarm.tm_sec = tmp;
234 NVRAM->buffer[0x1FF2] = val; 208 NVRAM->buffer[0x1FF2] = val;
235 - set_alarm(NVRAM, &tm); 209 + set_alarm(NVRAM);
236 } 210 }
237 break; 211 break;
238 case 0x1FF3: 212 case 0x1FF3:
239 /* alarm minutes */ 213 /* alarm minutes */
240 tmp = fromBCD(val & 0x7F); 214 tmp = fromBCD(val & 0x7F);
241 if (tmp >= 0 && tmp <= 59) { 215 if (tmp >= 0 && tmp <= 59) {
242 - get_alarm(NVRAM, &tm);  
243 - tm.tm_min = tmp; 216 + NVRAM->alarm.tm_min = tmp;
244 NVRAM->buffer[0x1FF3] = val; 217 NVRAM->buffer[0x1FF3] = val;
245 - set_alarm(NVRAM, &tm); 218 + set_alarm(NVRAM);
246 } 219 }
247 break; 220 break;
248 case 0x1FF4: 221 case 0x1FF4:
249 /* alarm hours */ 222 /* alarm hours */
250 tmp = fromBCD(val & 0x3F); 223 tmp = fromBCD(val & 0x3F);
251 if (tmp >= 0 && tmp <= 23) { 224 if (tmp >= 0 && tmp <= 23) {
252 - get_alarm(NVRAM, &tm);  
253 - tm.tm_hour = tmp; 225 + NVRAM->alarm.tm_hour = tmp;
254 NVRAM->buffer[0x1FF4] = val; 226 NVRAM->buffer[0x1FF4] = val;
255 - set_alarm(NVRAM, &tm); 227 + set_alarm(NVRAM);
256 } 228 }
257 break; 229 break;
258 case 0x1FF5: 230 case 0x1FF5:
259 /* alarm date */ 231 /* alarm date */
260 tmp = fromBCD(val & 0x1F); 232 tmp = fromBCD(val & 0x1F);
261 if (tmp != 0) { 233 if (tmp != 0) {
262 - get_alarm(NVRAM, &tm);  
263 - tm.tm_mday = tmp; 234 + NVRAM->alarm.tm_mday = tmp;
264 NVRAM->buffer[0x1FF5] = val; 235 NVRAM->buffer[0x1FF5] = val;
265 - set_alarm(NVRAM, &tm); 236 + set_alarm(NVRAM);
266 } 237 }
267 break; 238 break;
268 case 0x1FF6: 239 case 0x1FF6:
@@ -288,7 +259,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) @@ -288,7 +259,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
288 tm.tm_sec = tmp; 259 tm.tm_sec = tmp;
289 set_time(NVRAM, &tm); 260 set_time(NVRAM, &tm);
290 } 261 }
291 - if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) { 262 + if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) {
292 if (val & 0x80) { 263 if (val & 0x80) {
293 NVRAM->stop_time = time(NULL); 264 NVRAM->stop_time = time(NULL);
294 } else { 265 } else {
@@ -296,7 +267,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) @@ -296,7 +267,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
296 NVRAM->stop_time = 0; 267 NVRAM->stop_time = 0;
297 } 268 }
298 } 269 }
299 - NVRAM->buffer[addr] = val & 0x80; 270 + NVRAM->buffer[addr] = val & 0x80;
300 break; 271 break;
301 case 0x1FFA: 272 case 0x1FFA:
302 case 0x07FA: 273 case 0x07FA:
@@ -682,6 +653,7 @@ m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base, @@ -682,6 +653,7 @@ m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base,
682 s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s); 653 s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);
683 } 654 }
684 s->lock = 0; 655 s->lock = 0;
  656 + qemu_get_timedate(&s->alarm, 0);
685 657
686 qemu_register_reset(m48t59_reset, s); 658 qemu_register_reset(m48t59_reset, s);
687 save_base = mem_base ? mem_base : io_base; 659 save_base = mem_base ? mem_base : io_base;
hw/mc146818rtc.c
@@ -392,24 +392,14 @@ void rtc_set_date(RTCState *s, const struct tm *tm) @@ -392,24 +392,14 @@ void rtc_set_date(RTCState *s, const struct tm *tm)
392 392
393 static void rtc_set_date_from_host(RTCState *s) 393 static void rtc_set_date_from_host(RTCState *s)
394 { 394 {
395 - time_t ti;  
396 - struct tm *tm; 395 + struct tm tm;
397 int val; 396 int val;
398 397
399 /* set the CMOS date */ 398 /* set the CMOS date */
400 - if (rtc_start_date == -1) {  
401 - time(&ti);  
402 - if (rtc_utc)  
403 - tm = gmtime(&ti);  
404 - else  
405 - tm = localtime(&ti);  
406 - } else {  
407 - ti = rtc_start_date;  
408 - tm = gmtime(&ti);  
409 - }  
410 - rtc_set_date(s, tm); 399 + qemu_get_timedate(&tm, 0);
  400 + rtc_set_date(s, &tm);
411 401
412 - val = to_bcd(s, (tm->tm_year / 100) + 19); 402 + val = to_bcd(s, (tm.tm_year / 100) + 19);
413 rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val); 403 rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
414 rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val); 404 rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
415 } 405 }
hw/omap.c
@@ -4345,7 +4345,6 @@ struct omap_rtc_s { @@ -4345,7 +4345,6 @@ struct omap_rtc_s {
4345 int pm_am; 4345 int pm_am;
4346 int auto_comp; 4346 int auto_comp;
4347 int round; 4347 int round;
4348 - struct tm *(*convert)(const time_t *timep, struct tm *result);  
4349 struct tm alarm_tm; 4348 struct tm alarm_tm;
4350 time_t alarm_ti; 4349 time_t alarm_ti;
4351 4350
@@ -4668,7 +4667,7 @@ static void omap_rtc_tick(void *opaque) @@ -4668,7 +4667,7 @@ static void omap_rtc_tick(void *opaque)
4668 s->round = 0; 4667 s->round = 0;
4669 } 4668 }
4670 4669
4671 - localtime_r(&s->ti, &s->current_tm); 4670 + memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
4672 4671
4673 if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) { 4672 if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
4674 s->status |= 0x40; 4673 s->status |= 0x40;
@@ -4719,6 +4718,8 @@ static void omap_rtc_tick(void *opaque) @@ -4719,6 +4718,8 @@ static void omap_rtc_tick(void *opaque)
4719 4718
4720 static void omap_rtc_reset(struct omap_rtc_s *s) 4719 static void omap_rtc_reset(struct omap_rtc_s *s)
4721 { 4720 {
  4721 + struct tm tm;
  4722 +
4722 s->interrupts = 0; 4723 s->interrupts = 0;
4723 s->comp_reg = 0; 4724 s->comp_reg = 0;
4724 s->running = 0; 4725 s->running = 0;
@@ -4729,8 +4730,8 @@ static void omap_rtc_reset(struct omap_rtc_s *s) @@ -4729,8 +4730,8 @@ static void omap_rtc_reset(struct omap_rtc_s *s)
4729 memset(&s->alarm_tm, 0, sizeof(s->alarm_tm)); 4730 memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
4730 s->alarm_tm.tm_mday = 0x01; 4731 s->alarm_tm.tm_mday = 0x01;
4731 s->status = 1 << 7; 4732 s->status = 1 << 7;
4732 - time(&s->ti);  
4733 - s->ti = mktime(s->convert(&s->ti, &s->current_tm)); 4733 + qemu_get_timedate(&tm, 0);
  4734 + s->ti = mktime(&tm);
4734 4735
4735 omap_rtc_alarm_update(s); 4736 omap_rtc_alarm_update(s);
4736 omap_rtc_tick(s); 4737 omap_rtc_tick(s);
@@ -4747,7 +4748,6 @@ struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base, @@ -4747,7 +4748,6 @@ struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
4747 s->irq = irq[0]; 4748 s->irq = irq[0];
4748 s->alarm = irq[1]; 4749 s->alarm = irq[1];
4749 s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s); 4750 s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
4750 - s->convert = rtc_utc ? gmtime_r : localtime_r;  
4751 4751
4752 omap_rtc_reset(s); 4752 omap_rtc_reset(s);
4753 4753
hw/pl031.c
@@ -195,8 +195,7 @@ void pl031_init(uint32_t base, qemu_irq irq) @@ -195,8 +195,7 @@ void pl031_init(uint32_t base, qemu_irq irq)
195 { 195 {
196 int iomemtype; 196 int iomemtype;
197 pl031_state *s; 197 pl031_state *s;
198 - time_t ti;  
199 - struct tm *tm; 198 + struct tm tm;
200 199
201 s = qemu_mallocz(sizeof(pl031_state)); 200 s = qemu_mallocz(sizeof(pl031_state));
202 if (!s) 201 if (!s)
@@ -211,12 +210,8 @@ void pl031_init(uint32_t base, qemu_irq irq) @@ -211,12 +210,8 @@ void pl031_init(uint32_t base, qemu_irq irq)
211 s->base = base; 210 s->base = base;
212 s->irq = irq; 211 s->irq = irq;
213 /* ??? We assume vm_clock is zero at this point. */ 212 /* ??? We assume vm_clock is zero at this point. */
214 - time(&ti);  
215 - if (rtc_utc)  
216 - tm = gmtime(&ti);  
217 - else  
218 - tm = localtime(&ti);  
219 - s->tick_offset = mktime(tm); 213 + qemu_get_timedate(&tm, 0);
  214 + s->tick_offset = mktime(&tm);
220 215
221 s->timer = qemu_new_timer(vm_clock, pl031_interrupt, s); 216 s->timer = qemu_new_timer(vm_clock, pl031_interrupt, s);
222 } 217 }
hw/pxa2xx.c
@@ -1183,27 +1183,22 @@ static CPUWriteMemoryFunc *pxa2xx_rtc_writefn[] = { @@ -1183,27 +1183,22 @@ static CPUWriteMemoryFunc *pxa2xx_rtc_writefn[] = {
1183 1183
1184 static void pxa2xx_rtc_init(struct pxa2xx_state_s *s) 1184 static void pxa2xx_rtc_init(struct pxa2xx_state_s *s)
1185 { 1185 {
1186 - struct tm *tm;  
1187 - time_t ti; 1186 + struct tm tm;
1188 int wom; 1187 int wom;
1189 1188
1190 s->rttr = 0x7fff; 1189 s->rttr = 0x7fff;
1191 s->rtsr = 0; 1190 s->rtsr = 0;
1192 1191
1193 - time(&ti);  
1194 - if (rtc_utc)  
1195 - tm = gmtime(&ti);  
1196 - else  
1197 - tm = localtime(&ti);  
1198 - wom = ((tm->tm_mday - 1) / 7) + 1;  
1199 -  
1200 - s->last_rcnr = (uint32_t) ti;  
1201 - s->last_rdcr = (wom << 20) | ((tm->tm_wday + 1) << 17) |  
1202 - (tm->tm_hour << 12) | (tm->tm_min << 6) | tm->tm_sec;  
1203 - s->last_rycr = ((tm->tm_year + 1900) << 9) |  
1204 - ((tm->tm_mon + 1) << 5) | tm->tm_mday;  
1205 - s->last_swcr = (tm->tm_hour << 19) |  
1206 - (tm->tm_min << 13) | (tm->tm_sec << 7); 1192 + qemu_get_timedate(&tm, 0);
  1193 + wom = ((tm.tm_mday - 1) / 7) + 1;
  1194 +
  1195 + s->last_rcnr = (uint32_t) mktime(&tm);
  1196 + s->last_rdcr = (wom << 20) | ((tm.tm_wday + 1) << 17) |
  1197 + (tm.tm_hour << 12) | (tm.tm_min << 6) | tm.tm_sec;
  1198 + s->last_rycr = ((tm.tm_year + 1900) << 9) |
  1199 + ((tm.tm_mon + 1) << 5) | tm.tm_mday;
  1200 + s->last_swcr = (tm.tm_hour << 19) |
  1201 + (tm.tm_min << 13) | (tm.tm_sec << 7);
1207 s->last_rtcpicr = 0; 1202 s->last_rtcpicr = 0;
1208 s->last_hz = s->last_sw = s->last_pi = qemu_get_clock(rt_clock); 1203 s->last_hz = s->last_sw = s->last_pi = qemu_get_clock(rt_clock);
1209 1204
qemu-common.h
@@ -76,6 +76,9 @@ int qemu_bh_poll(void); @@ -76,6 +76,9 @@ int qemu_bh_poll(void);
76 76
77 uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c); 77 uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
78 78
  79 +void qemu_get_timedate(struct tm *tm, int offset);
  80 +int qemu_timedate_diff(struct tm *tm);
  81 +
79 /* cutils.c */ 82 /* cutils.c */
80 void pstrcpy(char *buf, int buf_size, const char *str); 83 void pstrcpy(char *buf, int buf_size, const char *str);
81 char *pstrcat(char *buf, int buf_size, const char *s); 84 char *pstrcat(char *buf, int buf_size, const char *s);
sysemu.h
@@ -71,8 +71,6 @@ void do_info_slirp(void); @@ -71,8 +71,6 @@ void do_info_slirp(void);
71 71
72 extern int ram_size; 72 extern int ram_size;
73 extern int bios_size; 73 extern int bios_size;
74 -extern int rtc_utc;  
75 -extern int rtc_start_date;  
76 extern int cirrus_vga_enabled; 74 extern int cirrus_vga_enabled;
77 extern int vmsvga_enabled; 75 extern int vmsvga_enabled;
78 extern int graphic_width; 76 extern int graphic_width;
@@ -180,8 +180,8 @@ int pit_min_timer_count = 0; @@ -180,8 +180,8 @@ int pit_min_timer_count = 0;
180 int nb_nics; 180 int nb_nics;
181 NICInfo nd_table[MAX_NICS]; 181 NICInfo nd_table[MAX_NICS];
182 int vm_running; 182 int vm_running;
183 -int rtc_utc = 1;  
184 -int rtc_start_date = -1; /* -1 means now */ 183 +static int rtc_utc = 1;
  184 +static int rtc_date_offset = -1; /* -1 means no change */
185 int cirrus_vga_enabled = 1; 185 int cirrus_vga_enabled = 1;
186 int vmsvga_enabled = 0; 186 int vmsvga_enabled = 0;
187 #ifdef TARGET_SPARC 187 #ifdef TARGET_SPARC
@@ -1565,6 +1565,43 @@ static void quit_timers(void) @@ -1565,6 +1565,43 @@ static void quit_timers(void)
1565 } 1565 }
1566 1566
1567 /***********************************************************/ 1567 /***********************************************************/
  1568 +/* host time/date access */
  1569 +void qemu_get_timedate(struct tm *tm, int offset)
  1570 +{
  1571 + time_t ti;
  1572 + struct tm *ret;
  1573 +
  1574 + time(&ti);
  1575 + ti += offset;
  1576 + if (rtc_date_offset == -1) {
  1577 + if (rtc_utc)
  1578 + ret = gmtime(&ti);
  1579 + else
  1580 + ret = localtime(&ti);
  1581 + } else {
  1582 + ti -= rtc_date_offset;
  1583 + ret = gmtime(&ti);
  1584 + }
  1585 +
  1586 + memcpy(tm, ret, sizeof(struct tm));
  1587 +}
  1588 +
  1589 +int qemu_timedate_diff(struct tm *tm)
  1590 +{
  1591 + time_t seconds;
  1592 +
  1593 + if (rtc_date_offset == -1)
  1594 + if (rtc_utc)
  1595 + seconds = mktimegm(tm);
  1596 + else
  1597 + seconds = mktime(tm);
  1598 + else
  1599 + seconds = mktimegm(tm) + rtc_date_offset;
  1600 +
  1601 + return seconds - time(NULL);
  1602 +}
  1603 +
  1604 +/***********************************************************/
1568 /* character device */ 1605 /* character device */
1569 1606
1570 static void qemu_chr_event(CharDriverState *s, int event) 1607 static void qemu_chr_event(CharDriverState *s, int event)
@@ -8698,8 +8735,9 @@ int main(int argc, char **argv) @@ -8698,8 +8735,9 @@ int main(int argc, char **argv)
8698 case QEMU_OPTION_startdate: 8735 case QEMU_OPTION_startdate:
8699 { 8736 {
8700 struct tm tm; 8737 struct tm tm;
  8738 + time_t rtc_start_date;
8701 if (!strcmp(optarg, "now")) { 8739 if (!strcmp(optarg, "now")) {
8702 - rtc_start_date = -1; 8740 + rtc_date_offset = -1;
8703 } else { 8741 } else {
8704 if (sscanf(optarg, "%d-%d-%dT%d:%d:%d", 8742 if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
8705 &tm.tm_year, 8743 &tm.tm_year,
@@ -8728,6 +8766,7 @@ int main(int argc, char **argv) @@ -8728,6 +8766,7 @@ int main(int argc, char **argv)
8728 "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n"); 8766 "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
8729 exit(1); 8767 exit(1);
8730 } 8768 }
  8769 + rtc_date_offset = time(NULL) - rtc_start_date;
8731 } 8770 }
8732 } 8771 }
8733 break; 8772 break;