Statistics
| Branch: | Revision:

root / hw / mc146818rtc.c @ e544a19f

History | View | Annotate | Download (22.8 kB)

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

    
50
#define RTC_SECONDS             0
51
#define RTC_SECONDS_ALARM       1
52
#define RTC_MINUTES             2
53
#define RTC_MINUTES_ALARM       3
54
#define RTC_HOURS               4
55
#define RTC_HOURS_ALARM         5
56
#define RTC_ALARM_DONT_CARE    0xC0
57

    
58
#define RTC_DAY_OF_WEEK         6
59
#define RTC_DAY_OF_MONTH        7
60
#define RTC_MONTH               8
61
#define RTC_YEAR                9
62

    
63
#define RTC_REG_A               10
64
#define RTC_REG_B               11
65
#define RTC_REG_C               12
66
#define RTC_REG_D               13
67

    
68
#define REG_A_UIP 0x80
69

    
70
#define REG_B_SET  0x80
71
#define REG_B_PIE  0x40
72
#define REG_B_AIE  0x20
73
#define REG_B_UIE  0x10
74
#define REG_B_SQWE 0x08
75
#define REG_B_DM   0x04
76
#define REG_B_24H  0x02
77

    
78
#define REG_C_UF   0x10
79
#define REG_C_IRQF 0x80
80
#define REG_C_PF   0x40
81
#define REG_C_AF   0x20
82

    
83
typedef struct RTCState {
84
    ISADevice dev;
85
    MemoryRegion io;
86
    uint8_t cmos_data[128];
87
    uint8_t cmos_index;
88
    struct tm current_tm;
89
    int32_t base_year;
90
    qemu_irq irq;
91
    qemu_irq sqw_irq;
92
    int it_shift;
93
    /* periodic timer */
94
    QEMUTimer *periodic_timer;
95
    int64_t next_periodic_time;
96
    /* second update */
97
    int64_t next_second_time;
98
    uint16_t irq_reinject_on_ack_count;
99
    uint32_t irq_coalesced;
100
    uint32_t period;
101
    QEMUTimer *coalesced_timer;
102
    QEMUTimer *second_timer;
103
    QEMUTimer *second_timer2;
104
    Notifier clock_reset_notifier;
105
    LostTickPolicy lost_tick_policy;
106
    Notifier suspend_notifier;
107
} RTCState;
108

    
109
static void rtc_set_time(RTCState *s);
110
static void rtc_copy_date(RTCState *s);
111

    
112
#ifdef TARGET_I386
113
static void rtc_coalesced_timer_update(RTCState *s)
114
{
115
    if (s->irq_coalesced == 0) {
116
        qemu_del_timer(s->coalesced_timer);
117
    } else {
118
        /* divide each RTC interval to 2 - 8 smaller intervals */
119
        int c = MIN(s->irq_coalesced, 7) + 1; 
120
        int64_t next_clock = qemu_get_clock_ns(rtc_clock) +
121
            muldiv64(s->period / c, get_ticks_per_sec(), 32768);
122
        qemu_mod_timer(s->coalesced_timer, next_clock);
123
    }
124
}
125

    
126
static void rtc_coalesced_timer(void *opaque)
127
{
128
    RTCState *s = opaque;
129

    
130
    if (s->irq_coalesced != 0) {
131
        apic_reset_irq_delivered();
132
        s->cmos_data[RTC_REG_C] |= 0xc0;
133
        DPRINTF_C("cmos: injecting from timer\n");
134
        qemu_irq_raise(s->irq);
135
        if (apic_get_irq_delivered()) {
136
            s->irq_coalesced--;
137
            DPRINTF_C("cmos: coalesced irqs decreased to %d\n",
138
                      s->irq_coalesced);
139
        }
140
    }
141

    
142
    rtc_coalesced_timer_update(s);
143
}
144
#endif
145

    
146
static void rtc_timer_update(RTCState *s, int64_t current_time)
147
{
148
    int period_code, period;
149
    int64_t cur_clock, next_irq_clock;
150

    
151
    period_code = s->cmos_data[RTC_REG_A] & 0x0f;
152
    if (period_code != 0
153
        && ((s->cmos_data[RTC_REG_B] & REG_B_PIE)
154
            || ((s->cmos_data[RTC_REG_B] & REG_B_SQWE) && s->sqw_irq))) {
155
        if (period_code <= 2)
156
            period_code += 7;
157
        /* period in 32 Khz cycles */
158
        period = 1 << (period_code - 1);
159
#ifdef TARGET_I386
160
        if (period != s->period) {
161
            s->irq_coalesced = (s->irq_coalesced * s->period) / period;
162
            DPRINTF_C("cmos: coalesced irqs scaled to %d\n", s->irq_coalesced);
163
        }
164
        s->period = period;
165
#endif
166
        /* compute 32 khz clock */
167
        cur_clock = muldiv64(current_time, 32768, get_ticks_per_sec());
168
        next_irq_clock = (cur_clock & ~(period - 1)) + period;
169
        s->next_periodic_time =
170
            muldiv64(next_irq_clock, get_ticks_per_sec(), 32768) + 1;
171
        qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
172
    } else {
173
#ifdef TARGET_I386
174
        s->irq_coalesced = 0;
175
#endif
176
        qemu_del_timer(s->periodic_timer);
177
    }
178
}
179

    
180
static void rtc_periodic_timer(void *opaque)
181
{
182
    RTCState *s = opaque;
183

    
184
    rtc_timer_update(s, s->next_periodic_time);
185
    s->cmos_data[RTC_REG_C] |= REG_C_PF;
186
    if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
187
        s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
188
#ifdef TARGET_I386
189
        if (s->lost_tick_policy == LOST_TICK_SLEW) {
190
            if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
191
                s->irq_reinject_on_ack_count = 0;                
192
            apic_reset_irq_delivered();
193
            qemu_irq_raise(s->irq);
194
            if (!apic_get_irq_delivered()) {
195
                s->irq_coalesced++;
196
                rtc_coalesced_timer_update(s);
197
                DPRINTF_C("cmos: coalesced irqs increased to %d\n",
198
                          s->irq_coalesced);
199
            }
200
        } else
201
#endif
202
        qemu_irq_raise(s->irq);
203
    }
204
    if (s->cmos_data[RTC_REG_B] & REG_B_SQWE) {
205
        /* Not square wave at all but we don't want 2048Hz interrupts!
206
           Must be seen as a pulse.  */
207
        qemu_irq_raise(s->sqw_irq);
208
    }
209
}
210

    
211
static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
212
{
213
    RTCState *s = opaque;
214

    
215
    if ((addr & 1) == 0) {
216
        s->cmos_index = data & 0x7f;
217
    } else {
218
        CMOS_DPRINTF("cmos: write index=0x%02x val=0x%02x\n",
219
                     s->cmos_index, data);
220
        switch(s->cmos_index) {
221
        case RTC_SECONDS_ALARM:
222
        case RTC_MINUTES_ALARM:
223
        case RTC_HOURS_ALARM:
224
            s->cmos_data[s->cmos_index] = data;
225
            break;
226
        case RTC_SECONDS:
227
        case RTC_MINUTES:
228
        case RTC_HOURS:
229
        case RTC_DAY_OF_WEEK:
230
        case RTC_DAY_OF_MONTH:
231
        case RTC_MONTH:
232
        case RTC_YEAR:
233
            s->cmos_data[s->cmos_index] = data;
234
            /* if in set mode, do not update the time */
235
            if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
236
                rtc_set_time(s);
237
            }
238
            break;
239
        case RTC_REG_A:
240
            /* UIP bit is read only */
241
            s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
242
                (s->cmos_data[RTC_REG_A] & REG_A_UIP);
243
            rtc_timer_update(s, qemu_get_clock_ns(rtc_clock));
244
            break;
245
        case RTC_REG_B:
246
            if (data & REG_B_SET) {
247
                /* set mode: reset UIP mode */
248
                s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
249
                data &= ~REG_B_UIE;
250
            } else {
251
                /* if disabling set mode, update the time */
252
                if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
253
                    rtc_set_time(s);
254
                }
255
            }
256
            if (((s->cmos_data[RTC_REG_B] ^ data) & (REG_B_DM | REG_B_24H)) &&
257
                !(data & REG_B_SET)) {
258
                /* If the time format has changed and not in set mode,
259
                   update the registers immediately. */
260
                s->cmos_data[RTC_REG_B] = data;
261
                rtc_copy_date(s);
262
            } else {
263
                s->cmos_data[RTC_REG_B] = data;
264
            }
265
            rtc_timer_update(s, qemu_get_clock_ns(rtc_clock));
266
            break;
267
        case RTC_REG_C:
268
        case RTC_REG_D:
269
            /* cannot write to them */
270
            break;
271
        default:
272
            s->cmos_data[s->cmos_index] = data;
273
            break;
274
        }
275
    }
276
}
277

    
278
static inline int rtc_to_bcd(RTCState *s, int a)
279
{
280
    if (s->cmos_data[RTC_REG_B] & REG_B_DM) {
281
        return a;
282
    } else {
283
        return ((a / 10) << 4) | (a % 10);
284
    }
285
}
286

    
287
static inline int rtc_from_bcd(RTCState *s, int a)
288
{
289
    if (s->cmos_data[RTC_REG_B] & REG_B_DM) {
290
        return a;
291
    } else {
292
        return ((a >> 4) * 10) + (a & 0x0f);
293
    }
294
}
295

    
296
static void rtc_set_time(RTCState *s)
297
{
298
    struct tm *tm = &s->current_tm;
299

    
300
    tm->tm_sec = rtc_from_bcd(s, s->cmos_data[RTC_SECONDS]);
301
    tm->tm_min = rtc_from_bcd(s, s->cmos_data[RTC_MINUTES]);
302
    tm->tm_hour = rtc_from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
303
    if (!(s->cmos_data[RTC_REG_B] & REG_B_24H)) {
304
        tm->tm_hour %= 12;
305
        if (s->cmos_data[RTC_HOURS] & 0x80) {
306
            tm->tm_hour += 12;
307
        }
308
    }
309
    tm->tm_wday = rtc_from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]) - 1;
310
    tm->tm_mday = rtc_from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
311
    tm->tm_mon = rtc_from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
312
    tm->tm_year = rtc_from_bcd(s, s->cmos_data[RTC_YEAR]) + s->base_year - 1900;
313

    
314
    rtc_change_mon_event(tm);
315
}
316

    
317
static void rtc_copy_date(RTCState *s)
318
{
319
    const struct tm *tm = &s->current_tm;
320
    int year;
321

    
322
    s->cmos_data[RTC_SECONDS] = rtc_to_bcd(s, tm->tm_sec);
323
    s->cmos_data[RTC_MINUTES] = rtc_to_bcd(s, tm->tm_min);
324
    if (s->cmos_data[RTC_REG_B] & REG_B_24H) {
325
        /* 24 hour format */
326
        s->cmos_data[RTC_HOURS] = rtc_to_bcd(s, tm->tm_hour);
327
    } else {
328
        /* 12 hour format */
329
        int h = (tm->tm_hour % 12) ? tm->tm_hour % 12 : 12;
330
        s->cmos_data[RTC_HOURS] = rtc_to_bcd(s, h);
331
        if (tm->tm_hour >= 12)
332
            s->cmos_data[RTC_HOURS] |= 0x80;
333
    }
334
    s->cmos_data[RTC_DAY_OF_WEEK] = rtc_to_bcd(s, tm->tm_wday + 1);
335
    s->cmos_data[RTC_DAY_OF_MONTH] = rtc_to_bcd(s, tm->tm_mday);
336
    s->cmos_data[RTC_MONTH] = rtc_to_bcd(s, tm->tm_mon + 1);
337
    year = (tm->tm_year - s->base_year) % 100;
338
    if (year < 0)
339
        year += 100;
340
    s->cmos_data[RTC_YEAR] = rtc_to_bcd(s, year);
341
}
342

    
343
/* month is between 0 and 11. */
344
static int get_days_in_month(int month, int year)
345
{
346
    static const int days_tab[12] = {
347
        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
348
    };
349
    int d;
350
    if ((unsigned )month >= 12)
351
        return 31;
352
    d = days_tab[month];
353
    if (month == 1) {
354
        if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
355
            d++;
356
    }
357
    return d;
358
}
359

    
360
/* update 'tm' to the next second */
361
static void rtc_next_second(struct tm *tm)
362
{
363
    int days_in_month;
364

    
365
    tm->tm_sec++;
366
    if ((unsigned)tm->tm_sec >= 60) {
367
        tm->tm_sec = 0;
368
        tm->tm_min++;
369
        if ((unsigned)tm->tm_min >= 60) {
370
            tm->tm_min = 0;
371
            tm->tm_hour++;
372
            if ((unsigned)tm->tm_hour >= 24) {
373
                tm->tm_hour = 0;
374
                /* next day */
375
                tm->tm_wday++;
376
                if ((unsigned)tm->tm_wday >= 7)
377
                    tm->tm_wday = 0;
378
                days_in_month = get_days_in_month(tm->tm_mon,
379
                                                  tm->tm_year + 1900);
380
                tm->tm_mday++;
381
                if (tm->tm_mday < 1) {
382
                    tm->tm_mday = 1;
383
                } else if (tm->tm_mday > days_in_month) {
384
                    tm->tm_mday = 1;
385
                    tm->tm_mon++;
386
                    if (tm->tm_mon >= 12) {
387
                        tm->tm_mon = 0;
388
                        tm->tm_year++;
389
                    }
390
                }
391
            }
392
        }
393
    }
394
}
395

    
396

    
397
static void rtc_update_second(void *opaque)
398
{
399
    RTCState *s = opaque;
400
    int64_t delay;
401

    
402
    /* if the oscillator is not in normal operation, we do not update */
403
    if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
404
        s->next_second_time += get_ticks_per_sec();
405
        qemu_mod_timer(s->second_timer, s->next_second_time);
406
    } else {
407
        rtc_next_second(&s->current_tm);
408

    
409
        if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
410
            /* update in progress bit */
411
            s->cmos_data[RTC_REG_A] |= REG_A_UIP;
412
        }
413
        /* should be 244 us = 8 / 32768 seconds, but currently the
414
           timers do not have the necessary resolution. */
415
        delay = (get_ticks_per_sec() * 1) / 100;
416
        if (delay < 1)
417
            delay = 1;
418
        qemu_mod_timer(s->second_timer2,
419
                       s->next_second_time + delay);
420
    }
421
}
422

    
423
static void rtc_update_second2(void *opaque)
424
{
425
    RTCState *s = opaque;
426

    
427
    if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
428
        rtc_copy_date(s);
429
    }
430

    
431
    /* check alarm */
432
    if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
433
         rtc_from_bcd(s, s->cmos_data[RTC_SECONDS_ALARM]) == s->current_tm.tm_sec) &&
434
        ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
435
         rtc_from_bcd(s, s->cmos_data[RTC_MINUTES_ALARM]) == s->current_tm.tm_min) &&
436
        ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
437
         rtc_from_bcd(s, s->cmos_data[RTC_HOURS_ALARM]) == s->current_tm.tm_hour)) {
438

    
439
        s->cmos_data[RTC_REG_C] |= REG_C_AF;
440
        if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
441
            qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC);
442
            qemu_irq_raise(s->irq);
443
            s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
444
        }
445
    }
446

    
447
    /* update ended interrupt */
448
    s->cmos_data[RTC_REG_C] |= REG_C_UF;
449
    if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
450
        s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
451
        qemu_irq_raise(s->irq);
452
    }
453

    
454
    /* clear update in progress bit */
455
    s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
456

    
457
    s->next_second_time += get_ticks_per_sec();
458
    qemu_mod_timer(s->second_timer, s->next_second_time);
459
}
460

    
461
static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
462
{
463
    RTCState *s = opaque;
464
    int ret;
465
    if ((addr & 1) == 0) {
466
        return 0xff;
467
    } else {
468
        switch(s->cmos_index) {
469
        case RTC_SECONDS:
470
        case RTC_MINUTES:
471
        case RTC_HOURS:
472
        case RTC_DAY_OF_WEEK:
473
        case RTC_DAY_OF_MONTH:
474
        case RTC_MONTH:
475
        case RTC_YEAR:
476
            ret = s->cmos_data[s->cmos_index];
477
            break;
478
        case RTC_REG_A:
479
            ret = s->cmos_data[s->cmos_index];
480
            break;
481
        case RTC_REG_C:
482
            ret = s->cmos_data[s->cmos_index];
483
            qemu_irq_lower(s->irq);
484
            s->cmos_data[RTC_REG_C] = 0x00;
485
#ifdef TARGET_I386
486
            if(s->irq_coalesced &&
487
                    (s->cmos_data[RTC_REG_B] & REG_B_PIE) &&
488
                    s->irq_reinject_on_ack_count < RTC_REINJECT_ON_ACK_COUNT) {
489
                s->irq_reinject_on_ack_count++;
490
                s->cmos_data[RTC_REG_C] |= REG_C_IRQF | REG_C_PF;
491
                apic_reset_irq_delivered();
492
                DPRINTF_C("cmos: injecting on ack\n");
493
                qemu_irq_raise(s->irq);
494
                if (apic_get_irq_delivered()) {
495
                    s->irq_coalesced--;
496
                    DPRINTF_C("cmos: coalesced irqs decreased to %d\n",
497
                              s->irq_coalesced);
498
                }
499
            }
500
#endif
501
            break;
502
        default:
503
            ret = s->cmos_data[s->cmos_index];
504
            break;
505
        }
506
        CMOS_DPRINTF("cmos: read index=0x%02x val=0x%02x\n",
507
                     s->cmos_index, ret);
508
        return ret;
509
    }
510
}
511

    
512
void rtc_set_memory(ISADevice *dev, int addr, int val)
513
{
514
    RTCState *s = DO_UPCAST(RTCState, dev, dev);
515
    if (addr >= 0 && addr <= 127)
516
        s->cmos_data[addr] = val;
517
}
518

    
519
void rtc_set_date(ISADevice *dev, const struct tm *tm)
520
{
521
    RTCState *s = DO_UPCAST(RTCState, dev, dev);
522
    s->current_tm = *tm;
523
    rtc_copy_date(s);
524
}
525

    
526
/* PC cmos mappings */
527
#define REG_IBM_CENTURY_BYTE        0x32
528
#define REG_IBM_PS2_CENTURY_BYTE    0x37
529

    
530
static void rtc_set_date_from_host(ISADevice *dev)
531
{
532
    RTCState *s = DO_UPCAST(RTCState, dev, dev);
533
    struct tm tm;
534
    int val;
535

    
536
    /* set the CMOS date */
537
    qemu_get_timedate(&tm, 0);
538
    rtc_set_date(dev, &tm);
539

    
540
    val = rtc_to_bcd(s, (tm.tm_year / 100) + 19);
541
    rtc_set_memory(dev, REG_IBM_CENTURY_BYTE, val);
542
    rtc_set_memory(dev, REG_IBM_PS2_CENTURY_BYTE, val);
543
}
544

    
545
static int rtc_post_load(void *opaque, int version_id)
546
{
547
#ifdef TARGET_I386
548
    RTCState *s = opaque;
549

    
550
    if (version_id >= 2) {
551
        if (s->lost_tick_policy == LOST_TICK_SLEW) {
552
            rtc_coalesced_timer_update(s);
553
        }
554
    }
555
#endif
556
    return 0;
557
}
558

    
559
static const VMStateDescription vmstate_rtc = {
560
    .name = "mc146818rtc",
561
    .version_id = 2,
562
    .minimum_version_id = 1,
563
    .minimum_version_id_old = 1,
564
    .post_load = rtc_post_load,
565
    .fields      = (VMStateField []) {
566
        VMSTATE_BUFFER(cmos_data, RTCState),
567
        VMSTATE_UINT8(cmos_index, RTCState),
568
        VMSTATE_INT32(current_tm.tm_sec, RTCState),
569
        VMSTATE_INT32(current_tm.tm_min, RTCState),
570
        VMSTATE_INT32(current_tm.tm_hour, RTCState),
571
        VMSTATE_INT32(current_tm.tm_wday, RTCState),
572
        VMSTATE_INT32(current_tm.tm_mday, RTCState),
573
        VMSTATE_INT32(current_tm.tm_mon, RTCState),
574
        VMSTATE_INT32(current_tm.tm_year, RTCState),
575
        VMSTATE_TIMER(periodic_timer, RTCState),
576
        VMSTATE_INT64(next_periodic_time, RTCState),
577
        VMSTATE_INT64(next_second_time, RTCState),
578
        VMSTATE_TIMER(second_timer, RTCState),
579
        VMSTATE_TIMER(second_timer2, RTCState),
580
        VMSTATE_UINT32_V(irq_coalesced, RTCState, 2),
581
        VMSTATE_UINT32_V(period, RTCState, 2),
582
        VMSTATE_END_OF_LIST()
583
    }
584
};
585

    
586
static void rtc_notify_clock_reset(Notifier *notifier, void *data)
587
{
588
    RTCState *s = container_of(notifier, RTCState, clock_reset_notifier);
589
    int64_t now = *(int64_t *)data;
590

    
591
    rtc_set_date_from_host(&s->dev);
592
    s->next_second_time = now + (get_ticks_per_sec() * 99) / 100;
593
    qemu_mod_timer(s->second_timer2, s->next_second_time);
594
    rtc_timer_update(s, now);
595
#ifdef TARGET_I386
596
    if (s->lost_tick_policy == LOST_TICK_SLEW) {
597
        rtc_coalesced_timer_update(s);
598
    }
599
#endif
600
}
601

    
602
/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
603
   BIOS will read it and start S3 resume at POST Entry */
604
static void rtc_notify_suspend(Notifier *notifier, void *data)
605
{
606
    RTCState *s = container_of(notifier, RTCState, suspend_notifier);
607
    rtc_set_memory(&s->dev, 0xF, 0xFE);
608
}
609

    
610
static void rtc_reset(void *opaque)
611
{
612
    RTCState *s = opaque;
613

    
614
    s->cmos_data[RTC_REG_B] &= ~(REG_B_PIE | REG_B_AIE | REG_B_SQWE);
615
    s->cmos_data[RTC_REG_C] &= ~(REG_C_UF | REG_C_IRQF | REG_C_PF | REG_C_AF);
616

    
617
    qemu_irq_lower(s->irq);
618

    
619
#ifdef TARGET_I386
620
    if (s->lost_tick_policy == LOST_TICK_SLEW) {
621
        s->irq_coalesced = 0;
622
    }
623
#endif
624
}
625

    
626
static const MemoryRegionPortio cmos_portio[] = {
627
    {0, 2, 1, .read = cmos_ioport_read, .write = cmos_ioport_write },
628
    PORTIO_END_OF_LIST(),
629
};
630

    
631
static const MemoryRegionOps cmos_ops = {
632
    .old_portio = cmos_portio
633
};
634

    
635
// FIXME add int32 visitor
636
static void visit_type_int32(Visitor *v, int *value, const char *name, Error **errp)
637
{
638
    int64_t val = *value;
639
    visit_type_int(v, &val, name, errp);
640
}
641

    
642
static void rtc_get_date(Object *obj, Visitor *v, void *opaque,
643
                         const char *name, Error **errp)
644
{
645
    ISADevice *isa = ISA_DEVICE(obj);
646
    RTCState *s = DO_UPCAST(RTCState, dev, isa);
647

    
648
    visit_start_struct(v, NULL, "struct tm", name, 0, errp);
649
    visit_type_int32(v, &s->current_tm.tm_year, "tm_year", errp);
650
    visit_type_int32(v, &s->current_tm.tm_mon, "tm_mon", errp);
651
    visit_type_int32(v, &s->current_tm.tm_mday, "tm_mday", errp);
652
    visit_type_int32(v, &s->current_tm.tm_hour, "tm_hour", errp);
653
    visit_type_int32(v, &s->current_tm.tm_min, "tm_min", errp);
654
    visit_type_int32(v, &s->current_tm.tm_sec, "tm_sec", errp);
655
    visit_end_struct(v, errp);
656
}
657

    
658
static int rtc_initfn(ISADevice *dev)
659
{
660
    RTCState *s = DO_UPCAST(RTCState, dev, dev);
661
    int base = 0x70;
662

    
663
    s->cmos_data[RTC_REG_A] = 0x26;
664
    s->cmos_data[RTC_REG_B] = 0x02;
665
    s->cmos_data[RTC_REG_C] = 0x00;
666
    s->cmos_data[RTC_REG_D] = 0x80;
667

    
668
    rtc_set_date_from_host(dev);
669

    
670
#ifdef TARGET_I386
671
    switch (s->lost_tick_policy) {
672
    case LOST_TICK_SLEW:
673
        s->coalesced_timer =
674
            qemu_new_timer_ns(rtc_clock, rtc_coalesced_timer, s);
675
        break;
676
    case LOST_TICK_DISCARD:
677
        break;
678
    default:
679
        return -EINVAL;
680
    }
681
#endif
682

    
683
    s->periodic_timer = qemu_new_timer_ns(rtc_clock, rtc_periodic_timer, s);
684
    s->second_timer = qemu_new_timer_ns(rtc_clock, rtc_update_second, s);
685
    s->second_timer2 = qemu_new_timer_ns(rtc_clock, rtc_update_second2, s);
686

    
687
    s->clock_reset_notifier.notify = rtc_notify_clock_reset;
688
    qemu_register_clock_reset_notifier(rtc_clock, &s->clock_reset_notifier);
689

    
690
    s->suspend_notifier.notify = rtc_notify_suspend;
691
    qemu_register_suspend_notifier(&s->suspend_notifier);
692

    
693
    s->next_second_time =
694
        qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100;
695
    qemu_mod_timer(s->second_timer2, s->next_second_time);
696

    
697
    memory_region_init_io(&s->io, &cmos_ops, s, "rtc", 2);
698
    isa_register_ioport(dev, &s->io, base);
699

    
700
    qdev_set_legacy_instance_id(&dev->qdev, base, 2);
701
    qemu_register_reset(rtc_reset, s);
702

    
703
    object_property_add(OBJECT(s), "date", "struct tm",
704
                        rtc_get_date, NULL, NULL, s, NULL);
705

    
706
    return 0;
707
}
708

    
709
ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
710
{
711
    ISADevice *dev;
712
    RTCState *s;
713

    
714
    dev = isa_create(bus, "mc146818rtc");
715
    s = DO_UPCAST(RTCState, dev, dev);
716
    qdev_prop_set_int32(&dev->qdev, "base_year", base_year);
717
    qdev_init_nofail(&dev->qdev);
718
    if (intercept_irq) {
719
        s->irq = intercept_irq;
720
    } else {
721
        isa_init_irq(dev, &s->irq, RTC_ISA_IRQ);
722
    }
723
    return dev;
724
}
725

    
726
static Property mc146818rtc_properties[] = {
727
    DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
728
    DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", RTCState,
729
                               lost_tick_policy, LOST_TICK_DISCARD),
730
    DEFINE_PROP_END_OF_LIST(),
731
};
732

    
733
static void rtc_class_initfn(ObjectClass *klass, void *data)
734
{
735
    DeviceClass *dc = DEVICE_CLASS(klass);
736
    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
737
    ic->init = rtc_initfn;
738
    dc->no_user = 1;
739
    dc->vmsd = &vmstate_rtc;
740
    dc->props = mc146818rtc_properties;
741
}
742

    
743
static TypeInfo mc146818rtc_info = {
744
    .name          = "mc146818rtc",
745
    .parent        = TYPE_ISA_DEVICE,
746
    .instance_size = sizeof(RTCState),
747
    .class_init    = rtc_class_initfn,
748
};
749

    
750
static void mc146818rtc_register_types(void)
751
{
752
    type_register_static(&mc146818rtc_info);
753
}
754

    
755
type_init(mc146818rtc_register_types)