Statistics
| Branch: | Revision:

root / hw / mc146818rtc.c @ 663447d4

History | View | Annotate | Download (21.5 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 "pc.h"
28
#include "apic.h"
29
#include "isa.h"
30
#include "mc146818rtc.h"
31

    
32
//#define DEBUG_CMOS
33
//#define DEBUG_COALESCED
34

    
35
#ifdef DEBUG_CMOS
36
# define CMOS_DPRINTF(format, ...)      printf(format, ## __VA_ARGS__)
37
#else
38
# define CMOS_DPRINTF(format, ...)      do { } while (0)
39
#endif
40

    
41
#ifdef DEBUG_COALESCED
42
# define DPRINTF_C(format, ...)      printf(format, ## __VA_ARGS__)
43
#else
44
# define DPRINTF_C(format, ...)      do { } while (0)
45
#endif
46

    
47
#define RTC_REINJECT_ON_ACK_COUNT 20
48

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

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

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

    
67
#define REG_A_UIP 0x80
68

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

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

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

    
106
static void rtc_set_time(RTCState *s);
107
static void rtc_copy_date(RTCState *s);
108

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

    
123
static void rtc_coalesced_timer(void *opaque)
124
{
125
    RTCState *s = opaque;
126

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

    
139
    rtc_coalesced_timer_update(s);
140
}
141
#endif
142

    
143
static void rtc_timer_update(RTCState *s, int64_t current_time)
144
{
145
    int period_code, period;
146
    int64_t cur_clock, next_irq_clock;
147

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

    
177
static void rtc_periodic_timer(void *opaque)
178
{
179
    RTCState *s = opaque;
180

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

    
208
static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
209
{
210
    RTCState *s = opaque;
211

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

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

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

    
293
static void rtc_set_time(RTCState *s)
294
{
295
    struct tm *tm = &s->current_tm;
296

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

    
311
    rtc_change_mon_event(tm);
312
}
313

    
314
static void rtc_copy_date(RTCState *s)
315
{
316
    const struct tm *tm = &s->current_tm;
317
    int year;
318

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

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

    
357
/* update 'tm' to the next second */
358
static void rtc_next_second(struct tm *tm)
359
{
360
    int days_in_month;
361

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

    
393

    
394
static void rtc_update_second(void *opaque)
395
{
396
    RTCState *s = opaque;
397
    int64_t delay;
398

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

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

    
420
static void rtc_update_second2(void *opaque)
421
{
422
    RTCState *s = opaque;
423

    
424
    if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
425
        rtc_copy_date(s);
426
    }
427

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

    
436
        s->cmos_data[RTC_REG_C] |= REG_C_AF;
437
        if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
438
            qemu_irq_raise(s->irq);
439
            s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
440
        }
441
    }
442

    
443
    /* update ended interrupt */
444
    s->cmos_data[RTC_REG_C] |= REG_C_UF;
445
    if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
446
        s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
447
        qemu_irq_raise(s->irq);
448
    }
449

    
450
    /* clear update in progress bit */
451
    s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
452

    
453
    s->next_second_time += get_ticks_per_sec();
454
    qemu_mod_timer(s->second_timer, s->next_second_time);
455
}
456

    
457
static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
458
{
459
    RTCState *s = opaque;
460
    int ret;
461
    if ((addr & 1) == 0) {
462
        return 0xff;
463
    } else {
464
        switch(s->cmos_index) {
465
        case RTC_SECONDS:
466
        case RTC_MINUTES:
467
        case RTC_HOURS:
468
        case RTC_DAY_OF_WEEK:
469
        case RTC_DAY_OF_MONTH:
470
        case RTC_MONTH:
471
        case RTC_YEAR:
472
            ret = s->cmos_data[s->cmos_index];
473
            break;
474
        case RTC_REG_A:
475
            ret = s->cmos_data[s->cmos_index];
476
            break;
477
        case RTC_REG_C:
478
            ret = s->cmos_data[s->cmos_index];
479
            qemu_irq_lower(s->irq);
480
#ifdef TARGET_I386
481
            if(s->irq_coalesced &&
482
                    s->irq_reinject_on_ack_count < RTC_REINJECT_ON_ACK_COUNT) {
483
                s->irq_reinject_on_ack_count++;
484
                apic_reset_irq_delivered();
485
                DPRINTF_C("cmos: injecting on ack\n");
486
                qemu_irq_raise(s->irq);
487
                if (apic_get_irq_delivered()) {
488
                    s->irq_coalesced--;
489
                    DPRINTF_C("cmos: coalesced irqs decreased to %d\n",
490
                              s->irq_coalesced);
491
                }
492
                break;
493
            }
494
#endif
495

    
496
            s->cmos_data[RTC_REG_C] = 0x00;
497
            break;
498
        default:
499
            ret = s->cmos_data[s->cmos_index];
500
            break;
501
        }
502
        CMOS_DPRINTF("cmos: read index=0x%02x val=0x%02x\n",
503
                     s->cmos_index, ret);
504
        return ret;
505
    }
506
}
507

    
508
void rtc_set_memory(ISADevice *dev, int addr, int val)
509
{
510
    RTCState *s = DO_UPCAST(RTCState, dev, dev);
511
    if (addr >= 0 && addr <= 127)
512
        s->cmos_data[addr] = val;
513
}
514

    
515
void rtc_set_date(ISADevice *dev, const struct tm *tm)
516
{
517
    RTCState *s = DO_UPCAST(RTCState, dev, dev);
518
    s->current_tm = *tm;
519
    rtc_copy_date(s);
520
}
521

    
522
/* PC cmos mappings */
523
#define REG_IBM_CENTURY_BYTE        0x32
524
#define REG_IBM_PS2_CENTURY_BYTE    0x37
525

    
526
static void rtc_set_date_from_host(ISADevice *dev)
527
{
528
    RTCState *s = DO_UPCAST(RTCState, dev, dev);
529
    struct tm tm;
530
    int val;
531

    
532
    /* set the CMOS date */
533
    qemu_get_timedate(&tm, 0);
534
    rtc_set_date(dev, &tm);
535

    
536
    val = rtc_to_bcd(s, (tm.tm_year / 100) + 19);
537
    rtc_set_memory(dev, REG_IBM_CENTURY_BYTE, val);
538
    rtc_set_memory(dev, REG_IBM_PS2_CENTURY_BYTE, val);
539
}
540

    
541
static int rtc_post_load(void *opaque, int version_id)
542
{
543
#ifdef TARGET_I386
544
    RTCState *s = opaque;
545

    
546
    if (version_id >= 2) {
547
        if (rtc_td_hack) {
548
            rtc_coalesced_timer_update(s);
549
        }
550
    }
551
#endif
552
    return 0;
553
}
554

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

    
582
static void rtc_notify_clock_reset(Notifier *notifier, void *data)
583
{
584
    RTCState *s = container_of(notifier, RTCState, clock_reset_notifier);
585
    int64_t now = *(int64_t *)data;
586

    
587
    rtc_set_date_from_host(&s->dev);
588
    s->next_second_time = now + (get_ticks_per_sec() * 99) / 100;
589
    qemu_mod_timer(s->second_timer2, s->next_second_time);
590
    rtc_timer_update(s, now);
591
#ifdef TARGET_I386
592
    if (rtc_td_hack) {
593
        rtc_coalesced_timer_update(s);
594
    }
595
#endif
596
}
597

    
598
static void rtc_reset(void *opaque)
599
{
600
    RTCState *s = opaque;
601

    
602
    s->cmos_data[RTC_REG_B] &= ~(REG_B_PIE | REG_B_AIE | REG_B_SQWE);
603
    s->cmos_data[RTC_REG_C] &= ~(REG_C_UF | REG_C_IRQF | REG_C_PF | REG_C_AF);
604

    
605
    qemu_irq_lower(s->irq);
606

    
607
#ifdef TARGET_I386
608
    if (rtc_td_hack)
609
            s->irq_coalesced = 0;
610
#endif
611
}
612

    
613
static const MemoryRegionPortio cmos_portio[] = {
614
    {0, 2, 1, .read = cmos_ioport_read, .write = cmos_ioport_write },
615
    PORTIO_END_OF_LIST(),
616
};
617

    
618
static const MemoryRegionOps cmos_ops = {
619
    .old_portio = cmos_portio
620
};
621

    
622
// FIXME add int32 visitor
623
static void visit_type_int32(Visitor *v, int *value, const char *name, Error **errp)
624
{
625
    int64_t val = *value;
626
    visit_type_int(v, &val, name, errp);
627
}
628

    
629
static void rtc_get_date(DeviceState *dev, Visitor *v, void *opaque,
630
                         const char *name, Error **errp)
631
{
632
    ISADevice *isa = DO_UPCAST(ISADevice, qdev, dev);
633
    RTCState *s = DO_UPCAST(RTCState, dev, isa);
634

    
635
    visit_start_struct(v, NULL, "struct tm", name, 0, errp);
636
    visit_type_int32(v, &s->current_tm.tm_year, "tm_year", errp);
637
    visit_type_int32(v, &s->current_tm.tm_mon, "tm_mon", errp);
638
    visit_type_int32(v, &s->current_tm.tm_mday, "tm_mday", errp);
639
    visit_type_int32(v, &s->current_tm.tm_hour, "tm_hour", errp);
640
    visit_type_int32(v, &s->current_tm.tm_min, "tm_min", errp);
641
    visit_type_int32(v, &s->current_tm.tm_sec, "tm_sec", errp);
642
    visit_end_struct(v, errp);
643
}
644

    
645
static int rtc_initfn(ISADevice *dev)
646
{
647
    RTCState *s = DO_UPCAST(RTCState, dev, dev);
648
    int base = 0x70;
649

    
650
    s->cmos_data[RTC_REG_A] = 0x26;
651
    s->cmos_data[RTC_REG_B] = 0x02;
652
    s->cmos_data[RTC_REG_C] = 0x00;
653
    s->cmos_data[RTC_REG_D] = 0x80;
654

    
655
    rtc_set_date_from_host(dev);
656

    
657
    s->periodic_timer = qemu_new_timer_ns(rtc_clock, rtc_periodic_timer, s);
658
#ifdef TARGET_I386
659
    if (rtc_td_hack)
660
        s->coalesced_timer =
661
            qemu_new_timer_ns(rtc_clock, rtc_coalesced_timer, s);
662
#endif
663
    s->second_timer = qemu_new_timer_ns(rtc_clock, rtc_update_second, s);
664
    s->second_timer2 = qemu_new_timer_ns(rtc_clock, rtc_update_second2, s);
665

    
666
    s->clock_reset_notifier.notify = rtc_notify_clock_reset;
667
    qemu_register_clock_reset_notifier(rtc_clock, &s->clock_reset_notifier);
668

    
669
    s->next_second_time =
670
        qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100;
671
    qemu_mod_timer(s->second_timer2, s->next_second_time);
672

    
673
    memory_region_init_io(&s->io, &cmos_ops, s, "rtc", 2);
674
    isa_register_ioport(dev, &s->io, base);
675

    
676
    qdev_set_legacy_instance_id(&dev->qdev, base, 2);
677
    qemu_register_reset(rtc_reset, s);
678

    
679
    qdev_property_add(&s->dev.qdev, "date", "struct tm",
680
                      rtc_get_date, NULL, NULL, s, NULL);
681

    
682
    return 0;
683
}
684

    
685
ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
686
{
687
    ISADevice *dev;
688
    RTCState *s;
689

    
690
    dev = isa_create(bus, "mc146818rtc");
691
    s = DO_UPCAST(RTCState, dev, dev);
692
    qdev_prop_set_int32(&dev->qdev, "base_year", base_year);
693
    qdev_init_nofail(&dev->qdev);
694
    if (intercept_irq) {
695
        s->irq = intercept_irq;
696
    } else {
697
        isa_init_irq(dev, &s->irq, RTC_ISA_IRQ);
698
    }
699
    return dev;
700
}
701

    
702
static ISADeviceInfo mc146818rtc_info = {
703
    .qdev.name     = "mc146818rtc",
704
    .qdev.size     = sizeof(RTCState),
705
    .qdev.no_user  = 1,
706
    .qdev.vmsd     = &vmstate_rtc,
707
    .init          = rtc_initfn,
708
    .qdev.props    = (Property[]) {
709
        DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
710
        DEFINE_PROP_END_OF_LIST(),
711
    }
712
};
713

    
714
static void mc146818rtc_register(void)
715
{
716
    isa_qdev_register(&mc146818rtc_info);
717
}
718
device_init(mc146818rtc_register)