]> git.proxmox.com Git - qemu.git/blob - hw/mc146818rtc.c
RTC: introduce RTC_CLOCK_RATE
[qemu.git] / hw / mc146818rtc.c
1 /*
2 * QEMU MC146818 RTC emulation
3 *
4 * Copyright (c) 2003-2004 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 #include "hw.h"
25 #include "qemu-timer.h"
26 #include "sysemu.h"
27 #include "mc146818rtc.h"
28
29 #ifdef TARGET_I386
30 #include "apic.h"
31 #endif
32
33 //#define DEBUG_CMOS
34 //#define DEBUG_COALESCED
35
36 #ifdef DEBUG_CMOS
37 # define CMOS_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
38 #else
39 # define CMOS_DPRINTF(format, ...) do { } while (0)
40 #endif
41
42 #ifdef DEBUG_COALESCED
43 # define DPRINTF_C(format, ...) printf(format, ## __VA_ARGS__)
44 #else
45 # define DPRINTF_C(format, ...) do { } while (0)
46 #endif
47
48 #define RTC_REINJECT_ON_ACK_COUNT 20
49 #define RTC_CLOCK_RATE 32768
50
51 typedef struct RTCState {
52 ISADevice dev;
53 MemoryRegion io;
54 uint8_t cmos_data[128];
55 uint8_t cmos_index;
56 struct tm current_tm;
57 int32_t base_year;
58 qemu_irq irq;
59 qemu_irq sqw_irq;
60 int it_shift;
61 /* periodic timer */
62 QEMUTimer *periodic_timer;
63 int64_t next_periodic_time;
64 /* second update */
65 int64_t next_second_time;
66 uint16_t irq_reinject_on_ack_count;
67 uint32_t irq_coalesced;
68 uint32_t period;
69 QEMUTimer *coalesced_timer;
70 QEMUTimer *second_timer;
71 QEMUTimer *second_timer2;
72 Notifier clock_reset_notifier;
73 LostTickPolicy lost_tick_policy;
74 Notifier suspend_notifier;
75 } RTCState;
76
77 static void rtc_set_time(RTCState *s);
78 static void rtc_copy_date(RTCState *s);
79
80 #ifdef TARGET_I386
81 static void rtc_coalesced_timer_update(RTCState *s)
82 {
83 if (s->irq_coalesced == 0) {
84 qemu_del_timer(s->coalesced_timer);
85 } else {
86 /* divide each RTC interval to 2 - 8 smaller intervals */
87 int c = MIN(s->irq_coalesced, 7) + 1;
88 int64_t next_clock = qemu_get_clock_ns(rtc_clock) +
89 muldiv64(s->period / c, get_ticks_per_sec(), RTC_CLOCK_RATE);
90 qemu_mod_timer(s->coalesced_timer, next_clock);
91 }
92 }
93
94 static void rtc_coalesced_timer(void *opaque)
95 {
96 RTCState *s = opaque;
97
98 if (s->irq_coalesced != 0) {
99 apic_reset_irq_delivered();
100 s->cmos_data[RTC_REG_C] |= 0xc0;
101 DPRINTF_C("cmos: injecting from timer\n");
102 qemu_irq_raise(s->irq);
103 if (apic_get_irq_delivered()) {
104 s->irq_coalesced--;
105 DPRINTF_C("cmos: coalesced irqs decreased to %d\n",
106 s->irq_coalesced);
107 }
108 }
109
110 rtc_coalesced_timer_update(s);
111 }
112 #endif
113
114 static void periodic_timer_update(RTCState *s, int64_t current_time)
115 {
116 int period_code, period;
117 int64_t cur_clock, next_irq_clock;
118
119 period_code = s->cmos_data[RTC_REG_A] & 0x0f;
120 if (period_code != 0
121 && ((s->cmos_data[RTC_REG_B] & REG_B_PIE)
122 || ((s->cmos_data[RTC_REG_B] & REG_B_SQWE) && s->sqw_irq))) {
123 if (period_code <= 2)
124 period_code += 7;
125 /* period in 32 Khz cycles */
126 period = 1 << (period_code - 1);
127 #ifdef TARGET_I386
128 if (period != s->period) {
129 s->irq_coalesced = (s->irq_coalesced * s->period) / period;
130 DPRINTF_C("cmos: coalesced irqs scaled to %d\n", s->irq_coalesced);
131 }
132 s->period = period;
133 #endif
134 /* compute 32 khz clock */
135 cur_clock = muldiv64(current_time, RTC_CLOCK_RATE, get_ticks_per_sec());
136 next_irq_clock = (cur_clock & ~(period - 1)) + period;
137 s->next_periodic_time =
138 muldiv64(next_irq_clock, get_ticks_per_sec(), RTC_CLOCK_RATE) + 1;
139 qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
140 } else {
141 #ifdef TARGET_I386
142 s->irq_coalesced = 0;
143 #endif
144 qemu_del_timer(s->periodic_timer);
145 }
146 }
147
148 static void rtc_periodic_timer(void *opaque)
149 {
150 RTCState *s = opaque;
151
152 periodic_timer_update(s, s->next_periodic_time);
153 s->cmos_data[RTC_REG_C] |= REG_C_PF;
154 if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
155 s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
156 #ifdef TARGET_I386
157 if (s->lost_tick_policy == LOST_TICK_SLEW) {
158 if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
159 s->irq_reinject_on_ack_count = 0;
160 apic_reset_irq_delivered();
161 qemu_irq_raise(s->irq);
162 if (!apic_get_irq_delivered()) {
163 s->irq_coalesced++;
164 rtc_coalesced_timer_update(s);
165 DPRINTF_C("cmos: coalesced irqs increased to %d\n",
166 s->irq_coalesced);
167 }
168 } else
169 #endif
170 qemu_irq_raise(s->irq);
171 }
172 if (s->cmos_data[RTC_REG_B] & REG_B_SQWE) {
173 /* Not square wave at all but we don't want 2048Hz interrupts!
174 Must be seen as a pulse. */
175 qemu_irq_raise(s->sqw_irq);
176 }
177 }
178
179 static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
180 {
181 RTCState *s = opaque;
182
183 if ((addr & 1) == 0) {
184 s->cmos_index = data & 0x7f;
185 } else {
186 CMOS_DPRINTF("cmos: write index=0x%02x val=0x%02x\n",
187 s->cmos_index, data);
188 switch(s->cmos_index) {
189 case RTC_SECONDS_ALARM:
190 case RTC_MINUTES_ALARM:
191 case RTC_HOURS_ALARM:
192 s->cmos_data[s->cmos_index] = data;
193 break;
194 case RTC_SECONDS:
195 case RTC_MINUTES:
196 case RTC_HOURS:
197 case RTC_DAY_OF_WEEK:
198 case RTC_DAY_OF_MONTH:
199 case RTC_MONTH:
200 case RTC_YEAR:
201 s->cmos_data[s->cmos_index] = data;
202 /* if in set mode, do not update the time */
203 if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
204 rtc_set_time(s);
205 }
206 break;
207 case RTC_REG_A:
208 /* UIP bit is read only */
209 s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
210 (s->cmos_data[RTC_REG_A] & REG_A_UIP);
211 periodic_timer_update(s, qemu_get_clock_ns(rtc_clock));
212 break;
213 case RTC_REG_B:
214 if (data & REG_B_SET) {
215 /* set mode: reset UIP mode */
216 s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
217 data &= ~REG_B_UIE;
218 } else {
219 /* if disabling set mode, update the time */
220 if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
221 rtc_set_time(s);
222 }
223 }
224 s->cmos_data[RTC_REG_B] = data;
225 periodic_timer_update(s, qemu_get_clock_ns(rtc_clock));
226 break;
227 case RTC_REG_C:
228 case RTC_REG_D:
229 /* cannot write to them */
230 break;
231 default:
232 s->cmos_data[s->cmos_index] = data;
233 break;
234 }
235 }
236 }
237
238 static inline int rtc_to_bcd(RTCState *s, int a)
239 {
240 if (s->cmos_data[RTC_REG_B] & REG_B_DM) {
241 return a;
242 } else {
243 return ((a / 10) << 4) | (a % 10);
244 }
245 }
246
247 static inline int rtc_from_bcd(RTCState *s, int a)
248 {
249 if (s->cmos_data[RTC_REG_B] & REG_B_DM) {
250 return a;
251 } else {
252 return ((a >> 4) * 10) + (a & 0x0f);
253 }
254 }
255
256 static void rtc_set_time(RTCState *s)
257 {
258 struct tm *tm = &s->current_tm;
259
260 tm->tm_sec = rtc_from_bcd(s, s->cmos_data[RTC_SECONDS]);
261 tm->tm_min = rtc_from_bcd(s, s->cmos_data[RTC_MINUTES]);
262 tm->tm_hour = rtc_from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
263 if (!(s->cmos_data[RTC_REG_B] & REG_B_24H)) {
264 tm->tm_hour %= 12;
265 if (s->cmos_data[RTC_HOURS] & 0x80) {
266 tm->tm_hour += 12;
267 }
268 }
269 tm->tm_wday = rtc_from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]) - 1;
270 tm->tm_mday = rtc_from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
271 tm->tm_mon = rtc_from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
272 tm->tm_year = rtc_from_bcd(s, s->cmos_data[RTC_YEAR]) + s->base_year - 1900;
273
274 rtc_change_mon_event(tm);
275 }
276
277 static void rtc_copy_date(RTCState *s)
278 {
279 const struct tm *tm = &s->current_tm;
280 int year;
281
282 s->cmos_data[RTC_SECONDS] = rtc_to_bcd(s, tm->tm_sec);
283 s->cmos_data[RTC_MINUTES] = rtc_to_bcd(s, tm->tm_min);
284 if (s->cmos_data[RTC_REG_B] & REG_B_24H) {
285 /* 24 hour format */
286 s->cmos_data[RTC_HOURS] = rtc_to_bcd(s, tm->tm_hour);
287 } else {
288 /* 12 hour format */
289 int h = (tm->tm_hour % 12) ? tm->tm_hour % 12 : 12;
290 s->cmos_data[RTC_HOURS] = rtc_to_bcd(s, h);
291 if (tm->tm_hour >= 12)
292 s->cmos_data[RTC_HOURS] |= 0x80;
293 }
294 s->cmos_data[RTC_DAY_OF_WEEK] = rtc_to_bcd(s, tm->tm_wday + 1);
295 s->cmos_data[RTC_DAY_OF_MONTH] = rtc_to_bcd(s, tm->tm_mday);
296 s->cmos_data[RTC_MONTH] = rtc_to_bcd(s, tm->tm_mon + 1);
297 year = (tm->tm_year - s->base_year) % 100;
298 if (year < 0)
299 year += 100;
300 s->cmos_data[RTC_YEAR] = rtc_to_bcd(s, year);
301 }
302
303 /* month is between 0 and 11. */
304 static int get_days_in_month(int month, int year)
305 {
306 static const int days_tab[12] = {
307 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
308 };
309 int d;
310 if ((unsigned )month >= 12)
311 return 31;
312 d = days_tab[month];
313 if (month == 1) {
314 if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
315 d++;
316 }
317 return d;
318 }
319
320 /* update 'tm' to the next second */
321 static void rtc_next_second(struct tm *tm)
322 {
323 int days_in_month;
324
325 tm->tm_sec++;
326 if ((unsigned)tm->tm_sec >= 60) {
327 tm->tm_sec = 0;
328 tm->tm_min++;
329 if ((unsigned)tm->tm_min >= 60) {
330 tm->tm_min = 0;
331 tm->tm_hour++;
332 if ((unsigned)tm->tm_hour >= 24) {
333 tm->tm_hour = 0;
334 /* next day */
335 tm->tm_wday++;
336 if ((unsigned)tm->tm_wday >= 7)
337 tm->tm_wday = 0;
338 days_in_month = get_days_in_month(tm->tm_mon,
339 tm->tm_year + 1900);
340 tm->tm_mday++;
341 if (tm->tm_mday < 1) {
342 tm->tm_mday = 1;
343 } else if (tm->tm_mday > days_in_month) {
344 tm->tm_mday = 1;
345 tm->tm_mon++;
346 if (tm->tm_mon >= 12) {
347 tm->tm_mon = 0;
348 tm->tm_year++;
349 }
350 }
351 }
352 }
353 }
354 }
355
356
357 static void rtc_update_second(void *opaque)
358 {
359 RTCState *s = opaque;
360 int64_t delay;
361
362 /* if the oscillator is not in normal operation, we do not update */
363 if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
364 s->next_second_time += get_ticks_per_sec();
365 qemu_mod_timer(s->second_timer, s->next_second_time);
366 } else {
367 rtc_next_second(&s->current_tm);
368
369 if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
370 /* update in progress bit */
371 s->cmos_data[RTC_REG_A] |= REG_A_UIP;
372 }
373 /* should be 244 us = 8 / RTC_CLOCK_RATE seconds, but currently the
374 timers do not have the necessary resolution. */
375 delay = (get_ticks_per_sec() * 1) / 100;
376 if (delay < 1)
377 delay = 1;
378 qemu_mod_timer(s->second_timer2,
379 s->next_second_time + delay);
380 }
381 }
382
383 static void rtc_update_second2(void *opaque)
384 {
385 RTCState *s = opaque;
386
387 if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
388 rtc_copy_date(s);
389 }
390
391 /* check alarm */
392 if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
393 rtc_from_bcd(s, s->cmos_data[RTC_SECONDS_ALARM]) == s->current_tm.tm_sec) &&
394 ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
395 rtc_from_bcd(s, s->cmos_data[RTC_MINUTES_ALARM]) == s->current_tm.tm_min) &&
396 ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
397 rtc_from_bcd(s, s->cmos_data[RTC_HOURS_ALARM]) == s->current_tm.tm_hour)) {
398
399 s->cmos_data[RTC_REG_C] |= REG_C_AF;
400 if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
401 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC);
402 qemu_irq_raise(s->irq);
403 s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
404 }
405 }
406
407 /* update ended interrupt */
408 s->cmos_data[RTC_REG_C] |= REG_C_UF;
409 if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
410 s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
411 qemu_irq_raise(s->irq);
412 }
413
414 /* clear update in progress bit */
415 s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
416
417 s->next_second_time += get_ticks_per_sec();
418 qemu_mod_timer(s->second_timer, s->next_second_time);
419 }
420
421 static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
422 {
423 RTCState *s = opaque;
424 int ret;
425 if ((addr & 1) == 0) {
426 return 0xff;
427 } else {
428 switch(s->cmos_index) {
429 case RTC_SECONDS:
430 case RTC_MINUTES:
431 case RTC_HOURS:
432 case RTC_DAY_OF_WEEK:
433 case RTC_DAY_OF_MONTH:
434 case RTC_MONTH:
435 case RTC_YEAR:
436 ret = s->cmos_data[s->cmos_index];
437 break;
438 case RTC_REG_A:
439 ret = s->cmos_data[s->cmos_index];
440 break;
441 case RTC_REG_C:
442 ret = s->cmos_data[s->cmos_index];
443 qemu_irq_lower(s->irq);
444 s->cmos_data[RTC_REG_C] = 0x00;
445 #ifdef TARGET_I386
446 if(s->irq_coalesced &&
447 (s->cmos_data[RTC_REG_B] & REG_B_PIE) &&
448 s->irq_reinject_on_ack_count < RTC_REINJECT_ON_ACK_COUNT) {
449 s->irq_reinject_on_ack_count++;
450 s->cmos_data[RTC_REG_C] |= REG_C_IRQF | REG_C_PF;
451 apic_reset_irq_delivered();
452 DPRINTF_C("cmos: injecting on ack\n");
453 qemu_irq_raise(s->irq);
454 if (apic_get_irq_delivered()) {
455 s->irq_coalesced--;
456 DPRINTF_C("cmos: coalesced irqs decreased to %d\n",
457 s->irq_coalesced);
458 }
459 }
460 #endif
461 break;
462 default:
463 ret = s->cmos_data[s->cmos_index];
464 break;
465 }
466 CMOS_DPRINTF("cmos: read index=0x%02x val=0x%02x\n",
467 s->cmos_index, ret);
468 return ret;
469 }
470 }
471
472 void rtc_set_memory(ISADevice *dev, int addr, int val)
473 {
474 RTCState *s = DO_UPCAST(RTCState, dev, dev);
475 if (addr >= 0 && addr <= 127)
476 s->cmos_data[addr] = val;
477 }
478
479 void rtc_set_date(ISADevice *dev, const struct tm *tm)
480 {
481 RTCState *s = DO_UPCAST(RTCState, dev, dev);
482 s->current_tm = *tm;
483 rtc_copy_date(s);
484 }
485
486 /* PC cmos mappings */
487 #define REG_IBM_CENTURY_BYTE 0x32
488 #define REG_IBM_PS2_CENTURY_BYTE 0x37
489
490 static void rtc_set_date_from_host(ISADevice *dev)
491 {
492 RTCState *s = DO_UPCAST(RTCState, dev, dev);
493 struct tm tm;
494 int val;
495
496 /* set the CMOS date */
497 qemu_get_timedate(&tm, 0);
498 rtc_set_date(dev, &tm);
499
500 val = rtc_to_bcd(s, (tm.tm_year / 100) + 19);
501 rtc_set_memory(dev, REG_IBM_CENTURY_BYTE, val);
502 rtc_set_memory(dev, REG_IBM_PS2_CENTURY_BYTE, val);
503 }
504
505 static int rtc_post_load(void *opaque, int version_id)
506 {
507 #ifdef TARGET_I386
508 RTCState *s = opaque;
509
510 if (version_id >= 2) {
511 if (s->lost_tick_policy == LOST_TICK_SLEW) {
512 rtc_coalesced_timer_update(s);
513 }
514 }
515 #endif
516 return 0;
517 }
518
519 static const VMStateDescription vmstate_rtc = {
520 .name = "mc146818rtc",
521 .version_id = 2,
522 .minimum_version_id = 1,
523 .minimum_version_id_old = 1,
524 .post_load = rtc_post_load,
525 .fields = (VMStateField []) {
526 VMSTATE_BUFFER(cmos_data, RTCState),
527 VMSTATE_UINT8(cmos_index, RTCState),
528 VMSTATE_INT32(current_tm.tm_sec, RTCState),
529 VMSTATE_INT32(current_tm.tm_min, RTCState),
530 VMSTATE_INT32(current_tm.tm_hour, RTCState),
531 VMSTATE_INT32(current_tm.tm_wday, RTCState),
532 VMSTATE_INT32(current_tm.tm_mday, RTCState),
533 VMSTATE_INT32(current_tm.tm_mon, RTCState),
534 VMSTATE_INT32(current_tm.tm_year, RTCState),
535 VMSTATE_TIMER(periodic_timer, RTCState),
536 VMSTATE_INT64(next_periodic_time, RTCState),
537 VMSTATE_INT64(next_second_time, RTCState),
538 VMSTATE_TIMER(second_timer, RTCState),
539 VMSTATE_TIMER(second_timer2, RTCState),
540 VMSTATE_UINT32_V(irq_coalesced, RTCState, 2),
541 VMSTATE_UINT32_V(period, RTCState, 2),
542 VMSTATE_END_OF_LIST()
543 }
544 };
545
546 static void rtc_notify_clock_reset(Notifier *notifier, void *data)
547 {
548 RTCState *s = container_of(notifier, RTCState, clock_reset_notifier);
549 int64_t now = *(int64_t *)data;
550
551 rtc_set_date_from_host(&s->dev);
552 s->next_second_time = now + (get_ticks_per_sec() * 99) / 100;
553 qemu_mod_timer(s->second_timer2, s->next_second_time);
554 periodic_timer_update(s, now);
555 #ifdef TARGET_I386
556 if (s->lost_tick_policy == LOST_TICK_SLEW) {
557 rtc_coalesced_timer_update(s);
558 }
559 #endif
560 }
561
562 /* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
563 BIOS will read it and start S3 resume at POST Entry */
564 static void rtc_notify_suspend(Notifier *notifier, void *data)
565 {
566 RTCState *s = container_of(notifier, RTCState, suspend_notifier);
567 rtc_set_memory(&s->dev, 0xF, 0xFE);
568 }
569
570 static void rtc_reset(void *opaque)
571 {
572 RTCState *s = opaque;
573
574 s->cmos_data[RTC_REG_B] &= ~(REG_B_PIE | REG_B_AIE | REG_B_SQWE);
575 s->cmos_data[RTC_REG_C] &= ~(REG_C_UF | REG_C_IRQF | REG_C_PF | REG_C_AF);
576
577 qemu_irq_lower(s->irq);
578
579 #ifdef TARGET_I386
580 if (s->lost_tick_policy == LOST_TICK_SLEW) {
581 s->irq_coalesced = 0;
582 }
583 #endif
584 }
585
586 static const MemoryRegionPortio cmos_portio[] = {
587 {0, 2, 1, .read = cmos_ioport_read, .write = cmos_ioport_write },
588 PORTIO_END_OF_LIST(),
589 };
590
591 static const MemoryRegionOps cmos_ops = {
592 .old_portio = cmos_portio
593 };
594
595 static void rtc_get_date(Object *obj, Visitor *v, void *opaque,
596 const char *name, Error **errp)
597 {
598 ISADevice *isa = ISA_DEVICE(obj);
599 RTCState *s = DO_UPCAST(RTCState, dev, isa);
600
601 visit_start_struct(v, NULL, "struct tm", name, 0, errp);
602 visit_type_int32(v, &s->current_tm.tm_year, "tm_year", errp);
603 visit_type_int32(v, &s->current_tm.tm_mon, "tm_mon", errp);
604 visit_type_int32(v, &s->current_tm.tm_mday, "tm_mday", errp);
605 visit_type_int32(v, &s->current_tm.tm_hour, "tm_hour", errp);
606 visit_type_int32(v, &s->current_tm.tm_min, "tm_min", errp);
607 visit_type_int32(v, &s->current_tm.tm_sec, "tm_sec", errp);
608 visit_end_struct(v, errp);
609 }
610
611 static int rtc_initfn(ISADevice *dev)
612 {
613 RTCState *s = DO_UPCAST(RTCState, dev, dev);
614 int base = 0x70;
615
616 s->cmos_data[RTC_REG_A] = 0x26;
617 s->cmos_data[RTC_REG_B] = 0x02;
618 s->cmos_data[RTC_REG_C] = 0x00;
619 s->cmos_data[RTC_REG_D] = 0x80;
620
621 rtc_set_date_from_host(dev);
622
623 #ifdef TARGET_I386
624 switch (s->lost_tick_policy) {
625 case LOST_TICK_SLEW:
626 s->coalesced_timer =
627 qemu_new_timer_ns(rtc_clock, rtc_coalesced_timer, s);
628 break;
629 case LOST_TICK_DISCARD:
630 break;
631 default:
632 return -EINVAL;
633 }
634 #endif
635
636 s->periodic_timer = qemu_new_timer_ns(rtc_clock, rtc_periodic_timer, s);
637 s->second_timer = qemu_new_timer_ns(rtc_clock, rtc_update_second, s);
638 s->second_timer2 = qemu_new_timer_ns(rtc_clock, rtc_update_second2, s);
639
640 s->clock_reset_notifier.notify = rtc_notify_clock_reset;
641 qemu_register_clock_reset_notifier(rtc_clock, &s->clock_reset_notifier);
642
643 s->suspend_notifier.notify = rtc_notify_suspend;
644 qemu_register_suspend_notifier(&s->suspend_notifier);
645
646 s->next_second_time =
647 qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100;
648 qemu_mod_timer(s->second_timer2, s->next_second_time);
649
650 memory_region_init_io(&s->io, &cmos_ops, s, "rtc", 2);
651 isa_register_ioport(dev, &s->io, base);
652
653 qdev_set_legacy_instance_id(&dev->qdev, base, 2);
654 qemu_register_reset(rtc_reset, s);
655
656 object_property_add(OBJECT(s), "date", "struct tm",
657 rtc_get_date, NULL, NULL, s, NULL);
658
659 return 0;
660 }
661
662 ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
663 {
664 ISADevice *dev;
665 RTCState *s;
666
667 dev = isa_create(bus, "mc146818rtc");
668 s = DO_UPCAST(RTCState, dev, dev);
669 qdev_prop_set_int32(&dev->qdev, "base_year", base_year);
670 qdev_init_nofail(&dev->qdev);
671 if (intercept_irq) {
672 s->irq = intercept_irq;
673 } else {
674 isa_init_irq(dev, &s->irq, RTC_ISA_IRQ);
675 }
676 return dev;
677 }
678
679 static Property mc146818rtc_properties[] = {
680 DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
681 DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", RTCState,
682 lost_tick_policy, LOST_TICK_DISCARD),
683 DEFINE_PROP_END_OF_LIST(),
684 };
685
686 static void rtc_class_initfn(ObjectClass *klass, void *data)
687 {
688 DeviceClass *dc = DEVICE_CLASS(klass);
689 ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
690 ic->init = rtc_initfn;
691 dc->no_user = 1;
692 dc->vmsd = &vmstate_rtc;
693 dc->props = mc146818rtc_properties;
694 }
695
696 static TypeInfo mc146818rtc_info = {
697 .name = "mc146818rtc",
698 .parent = TYPE_ISA_DEVICE,
699 .instance_size = sizeof(RTCState),
700 .class_init = rtc_class_initfn,
701 };
702
703 static void mc146818rtc_register_types(void)
704 {
705 type_register_static(&mc146818rtc_info);
706 }
707
708 type_init(mc146818rtc_register_types)