Statistics
| Branch: | Revision:

root / hw / mc146818rtc.c @ 8da3ff18

History | View | Annotate | Download (16.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 "pc.h"
28
#include "isa.h"
29

    
30
//#define DEBUG_CMOS
31

    
32
#define RTC_SECONDS             0
33
#define RTC_SECONDS_ALARM       1
34
#define RTC_MINUTES             2
35
#define RTC_MINUTES_ALARM       3
36
#define RTC_HOURS               4
37
#define RTC_HOURS_ALARM         5
38
#define RTC_ALARM_DONT_CARE    0xC0
39

    
40
#define RTC_DAY_OF_WEEK         6
41
#define RTC_DAY_OF_MONTH        7
42
#define RTC_MONTH               8
43
#define RTC_YEAR                9
44

    
45
#define RTC_REG_A               10
46
#define RTC_REG_B               11
47
#define RTC_REG_C               12
48
#define RTC_REG_D               13
49

    
50
#define REG_A_UIP 0x80
51

    
52
#define REG_B_SET 0x80
53
#define REG_B_PIE 0x40
54
#define REG_B_AIE 0x20
55
#define REG_B_UIE 0x10
56

    
57
struct RTCState {
58
    uint8_t cmos_data[128];
59
    uint8_t cmos_index;
60
    struct tm current_tm;
61
    qemu_irq irq;
62
    int it_shift;
63
    /* periodic timer */
64
    QEMUTimer *periodic_timer;
65
    int64_t next_periodic_time;
66
    /* second update */
67
    int64_t next_second_time;
68
    QEMUTimer *second_timer;
69
    QEMUTimer *second_timer2;
70
};
71

    
72
static void rtc_set_time(RTCState *s);
73
static void rtc_copy_date(RTCState *s);
74

    
75
static void rtc_timer_update(RTCState *s, int64_t current_time)
76
{
77
    int period_code, period;
78
    int64_t cur_clock, next_irq_clock;
79

    
80
    period_code = s->cmos_data[RTC_REG_A] & 0x0f;
81
    if (period_code != 0 &&
82
        (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
83
        if (period_code <= 2)
84
            period_code += 7;
85
        /* period in 32 Khz cycles */
86
        period = 1 << (period_code - 1);
87
        /* compute 32 khz clock */
88
        cur_clock = muldiv64(current_time, 32768, ticks_per_sec);
89
        next_irq_clock = (cur_clock & ~(period - 1)) + period;
90
        s->next_periodic_time = muldiv64(next_irq_clock, ticks_per_sec, 32768) + 1;
91
        qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
92
    } else {
93
        qemu_del_timer(s->periodic_timer);
94
    }
95
}
96

    
97
static void rtc_periodic_timer(void *opaque)
98
{
99
    RTCState *s = opaque;
100

    
101
    rtc_timer_update(s, s->next_periodic_time);
102
    s->cmos_data[RTC_REG_C] |= 0xc0;
103
    qemu_irq_raise(s->irq);
104
}
105

    
106
static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
107
{
108
    RTCState *s = opaque;
109

    
110
    if ((addr & 1) == 0) {
111
        s->cmos_index = data & 0x7f;
112
    } else {
113
#ifdef DEBUG_CMOS
114
        printf("cmos: write index=0x%02x val=0x%02x\n",
115
               s->cmos_index, data);
116
#endif
117
        switch(s->cmos_index) {
118
        case RTC_SECONDS_ALARM:
119
        case RTC_MINUTES_ALARM:
120
        case RTC_HOURS_ALARM:
121
            /* XXX: not supported */
122
            s->cmos_data[s->cmos_index] = data;
123
            break;
124
        case RTC_SECONDS:
125
        case RTC_MINUTES:
126
        case RTC_HOURS:
127
        case RTC_DAY_OF_WEEK:
128
        case RTC_DAY_OF_MONTH:
129
        case RTC_MONTH:
130
        case RTC_YEAR:
131
            s->cmos_data[s->cmos_index] = data;
132
            /* if in set mode, do not update the time */
133
            if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
134
                rtc_set_time(s);
135
            }
136
            break;
137
        case RTC_REG_A:
138
            /* UIP bit is read only */
139
            s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
140
                (s->cmos_data[RTC_REG_A] & REG_A_UIP);
141
            rtc_timer_update(s, qemu_get_clock(vm_clock));
142
            break;
143
        case RTC_REG_B:
144
            if (data & REG_B_SET) {
145
                /* set mode: reset UIP mode */
146
                s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
147
                data &= ~REG_B_UIE;
148
            } else {
149
                /* if disabling set mode, update the time */
150
                if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
151
                    rtc_set_time(s);
152
                }
153
            }
154
            s->cmos_data[RTC_REG_B] = data;
155
            rtc_timer_update(s, qemu_get_clock(vm_clock));
156
            break;
157
        case RTC_REG_C:
158
        case RTC_REG_D:
159
            /* cannot write to them */
160
            break;
161
        default:
162
            s->cmos_data[s->cmos_index] = data;
163
            break;
164
        }
165
    }
166
}
167

    
168
static inline int to_bcd(RTCState *s, int a)
169
{
170
    if (s->cmos_data[RTC_REG_B] & 0x04) {
171
        return a;
172
    } else {
173
        return ((a / 10) << 4) | (a % 10);
174
    }
175
}
176

    
177
static inline int from_bcd(RTCState *s, int a)
178
{
179
    if (s->cmos_data[RTC_REG_B] & 0x04) {
180
        return a;
181
    } else {
182
        return ((a >> 4) * 10) + (a & 0x0f);
183
    }
184
}
185

    
186
static void rtc_set_time(RTCState *s)
187
{
188
    struct tm *tm = &s->current_tm;
189

    
190
    tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]);
191
    tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]);
192
    tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
193
    if (!(s->cmos_data[RTC_REG_B] & 0x02) &&
194
        (s->cmos_data[RTC_HOURS] & 0x80)) {
195
        tm->tm_hour += 12;
196
    }
197
    tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]);
198
    tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
199
    tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
200
    tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + 100;
201
}
202

    
203
static void rtc_copy_date(RTCState *s)
204
{
205
    const struct tm *tm = &s->current_tm;
206

    
207
    s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
208
    s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
209
    if (s->cmos_data[RTC_REG_B] & 0x02) {
210
        /* 24 hour format */
211
        s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour);
212
    } else {
213
        /* 12 hour format */
214
        s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12);
215
        if (tm->tm_hour >= 12)
216
            s->cmos_data[RTC_HOURS] |= 0x80;
217
    }
218
    s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday);
219
    s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday);
220
    s->cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1);
221
    s->cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100);
222
}
223

    
224
/* month is between 0 and 11. */
225
static int get_days_in_month(int month, int year)
226
{
227
    static const int days_tab[12] = {
228
        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
229
    };
230
    int d;
231
    if ((unsigned )month >= 12)
232
        return 31;
233
    d = days_tab[month];
234
    if (month == 1) {
235
        if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
236
            d++;
237
    }
238
    return d;
239
}
240

    
241
/* update 'tm' to the next second */
242
static void rtc_next_second(struct tm *tm)
243
{
244
    int days_in_month;
245

    
246
    tm->tm_sec++;
247
    if ((unsigned)tm->tm_sec >= 60) {
248
        tm->tm_sec = 0;
249
        tm->tm_min++;
250
        if ((unsigned)tm->tm_min >= 60) {
251
            tm->tm_min = 0;
252
            tm->tm_hour++;
253
            if ((unsigned)tm->tm_hour >= 24) {
254
                tm->tm_hour = 0;
255
                /* next day */
256
                tm->tm_wday++;
257
                if ((unsigned)tm->tm_wday >= 7)
258
                    tm->tm_wday = 0;
259
                days_in_month = get_days_in_month(tm->tm_mon,
260
                                                  tm->tm_year + 1900);
261
                tm->tm_mday++;
262
                if (tm->tm_mday < 1) {
263
                    tm->tm_mday = 1;
264
                } else if (tm->tm_mday > days_in_month) {
265
                    tm->tm_mday = 1;
266
                    tm->tm_mon++;
267
                    if (tm->tm_mon >= 12) {
268
                        tm->tm_mon = 0;
269
                        tm->tm_year++;
270
                    }
271
                }
272
            }
273
        }
274
    }
275
}
276

    
277

    
278
static void rtc_update_second(void *opaque)
279
{
280
    RTCState *s = opaque;
281
    int64_t delay;
282

    
283
    /* if the oscillator is not in normal operation, we do not update */
284
    if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
285
        s->next_second_time += ticks_per_sec;
286
        qemu_mod_timer(s->second_timer, s->next_second_time);
287
    } else {
288
        rtc_next_second(&s->current_tm);
289

    
290
        if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
291
            /* update in progress bit */
292
            s->cmos_data[RTC_REG_A] |= REG_A_UIP;
293
        }
294
        /* should be 244 us = 8 / 32768 seconds, but currently the
295
           timers do not have the necessary resolution. */
296
        delay = (ticks_per_sec * 1) / 100;
297
        if (delay < 1)
298
            delay = 1;
299
        qemu_mod_timer(s->second_timer2,
300
                       s->next_second_time + delay);
301
    }
302
}
303

    
304
static void rtc_update_second2(void *opaque)
305
{
306
    RTCState *s = opaque;
307

    
308
    if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
309
        rtc_copy_date(s);
310
    }
311

    
312
    /* check alarm */
313
    if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
314
        if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
315
             s->cmos_data[RTC_SECONDS_ALARM] == s->current_tm.tm_sec) &&
316
            ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
317
             s->cmos_data[RTC_MINUTES_ALARM] == s->current_tm.tm_mon) &&
318
            ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
319
             s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) {
320

    
321
            s->cmos_data[RTC_REG_C] |= 0xa0;
322
            qemu_irq_raise(s->irq);
323
        }
324
    }
325

    
326
    /* update ended interrupt */
327
    if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
328
        s->cmos_data[RTC_REG_C] |= 0x90;
329
        qemu_irq_raise(s->irq);
330
    }
331

    
332
    /* clear update in progress bit */
333
    s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
334

    
335
    s->next_second_time += ticks_per_sec;
336
    qemu_mod_timer(s->second_timer, s->next_second_time);
337
}
338

    
339
static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
340
{
341
    RTCState *s = opaque;
342
    int ret;
343
    if ((addr & 1) == 0) {
344
        return 0xff;
345
    } else {
346
        switch(s->cmos_index) {
347
        case RTC_SECONDS:
348
        case RTC_MINUTES:
349
        case RTC_HOURS:
350
        case RTC_DAY_OF_WEEK:
351
        case RTC_DAY_OF_MONTH:
352
        case RTC_MONTH:
353
        case RTC_YEAR:
354
            ret = s->cmos_data[s->cmos_index];
355
            break;
356
        case RTC_REG_A:
357
            ret = s->cmos_data[s->cmos_index];
358
            break;
359
        case RTC_REG_C:
360
            ret = s->cmos_data[s->cmos_index];
361
            qemu_irq_lower(s->irq);
362
            s->cmos_data[RTC_REG_C] = 0x00;
363
            break;
364
        default:
365
            ret = s->cmos_data[s->cmos_index];
366
            break;
367
        }
368
#ifdef DEBUG_CMOS
369
        printf("cmos: read index=0x%02x val=0x%02x\n",
370
               s->cmos_index, ret);
371
#endif
372
        return ret;
373
    }
374
}
375

    
376
void rtc_set_memory(RTCState *s, int addr, int val)
377
{
378
    if (addr >= 0 && addr <= 127)
379
        s->cmos_data[addr] = val;
380
}
381

    
382
void rtc_set_date(RTCState *s, const struct tm *tm)
383
{
384
    s->current_tm = *tm;
385
    rtc_copy_date(s);
386
}
387

    
388
/* PC cmos mappings */
389
#define REG_IBM_CENTURY_BYTE        0x32
390
#define REG_IBM_PS2_CENTURY_BYTE    0x37
391

    
392
static void rtc_set_date_from_host(RTCState *s)
393
{
394
    struct tm tm;
395
    int val;
396

    
397
    /* set the CMOS date */
398
    qemu_get_timedate(&tm, 0);
399
    rtc_set_date(s, &tm);
400

    
401
    val = to_bcd(s, (tm.tm_year / 100) + 19);
402
    rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
403
    rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
404
}
405

    
406
static void rtc_save(QEMUFile *f, void *opaque)
407
{
408
    RTCState *s = opaque;
409

    
410
    qemu_put_buffer(f, s->cmos_data, 128);
411
    qemu_put_8s(f, &s->cmos_index);
412

    
413
    qemu_put_be32(f, s->current_tm.tm_sec);
414
    qemu_put_be32(f, s->current_tm.tm_min);
415
    qemu_put_be32(f, s->current_tm.tm_hour);
416
    qemu_put_be32(f, s->current_tm.tm_wday);
417
    qemu_put_be32(f, s->current_tm.tm_mday);
418
    qemu_put_be32(f, s->current_tm.tm_mon);
419
    qemu_put_be32(f, s->current_tm.tm_year);
420

    
421
    qemu_put_timer(f, s->periodic_timer);
422
    qemu_put_be64(f, s->next_periodic_time);
423

    
424
    qemu_put_be64(f, s->next_second_time);
425
    qemu_put_timer(f, s->second_timer);
426
    qemu_put_timer(f, s->second_timer2);
427
}
428

    
429
static int rtc_load(QEMUFile *f, void *opaque, int version_id)
430
{
431
    RTCState *s = opaque;
432

    
433
    if (version_id != 1)
434
        return -EINVAL;
435

    
436
    qemu_get_buffer(f, s->cmos_data, 128);
437
    qemu_get_8s(f, &s->cmos_index);
438

    
439
    s->current_tm.tm_sec=qemu_get_be32(f);
440
    s->current_tm.tm_min=qemu_get_be32(f);
441
    s->current_tm.tm_hour=qemu_get_be32(f);
442
    s->current_tm.tm_wday=qemu_get_be32(f);
443
    s->current_tm.tm_mday=qemu_get_be32(f);
444
    s->current_tm.tm_mon=qemu_get_be32(f);
445
    s->current_tm.tm_year=qemu_get_be32(f);
446

    
447
    qemu_get_timer(f, s->periodic_timer);
448
    s->next_periodic_time=qemu_get_be64(f);
449

    
450
    s->next_second_time=qemu_get_be64(f);
451
    qemu_get_timer(f, s->second_timer);
452
    qemu_get_timer(f, s->second_timer2);
453
    return 0;
454
}
455

    
456
RTCState *rtc_init(int base, qemu_irq irq)
457
{
458
    RTCState *s;
459

    
460
    s = qemu_mallocz(sizeof(RTCState));
461
    if (!s)
462
        return NULL;
463

    
464
    s->irq = irq;
465
    s->cmos_data[RTC_REG_A] = 0x26;
466
    s->cmos_data[RTC_REG_B] = 0x02;
467
    s->cmos_data[RTC_REG_C] = 0x00;
468
    s->cmos_data[RTC_REG_D] = 0x80;
469

    
470
    rtc_set_date_from_host(s);
471

    
472
    s->periodic_timer = qemu_new_timer(vm_clock,
473
                                       rtc_periodic_timer, s);
474
    s->second_timer = qemu_new_timer(vm_clock,
475
                                     rtc_update_second, s);
476
    s->second_timer2 = qemu_new_timer(vm_clock,
477
                                      rtc_update_second2, s);
478

    
479
    s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
480
    qemu_mod_timer(s->second_timer2, s->next_second_time);
481

    
482
    register_ioport_write(base, 2, 1, cmos_ioport_write, s);
483
    register_ioport_read(base, 2, 1, cmos_ioport_read, s);
484

    
485
    register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
486
    return s;
487
}
488

    
489
/* Memory mapped interface */
490
static uint32_t cmos_mm_readb (void *opaque, target_phys_addr_t addr)
491
{
492
    RTCState *s = opaque;
493

    
494
    return cmos_ioport_read(s, addr >> s->it_shift) & 0xFF;
495
}
496

    
497
static void cmos_mm_writeb (void *opaque,
498
                            target_phys_addr_t addr, uint32_t value)
499
{
500
    RTCState *s = opaque;
501

    
502
    cmos_ioport_write(s, addr >> s->it_shift, value & 0xFF);
503
}
504

    
505
static uint32_t cmos_mm_readw (void *opaque, target_phys_addr_t addr)
506
{
507
    RTCState *s = opaque;
508
    uint32_t val;
509

    
510
    val = cmos_ioport_read(s, addr >> s->it_shift) & 0xFFFF;
511
#ifdef TARGET_WORDS_BIGENDIAN
512
    val = bswap16(val);
513
#endif
514
    return val;
515
}
516

    
517
static void cmos_mm_writew (void *opaque,
518
                            target_phys_addr_t addr, uint32_t value)
519
{
520
    RTCState *s = opaque;
521
#ifdef TARGET_WORDS_BIGENDIAN
522
    value = bswap16(value);
523
#endif
524
    cmos_ioport_write(s, addr >> s->it_shift, value & 0xFFFF);
525
}
526

    
527
static uint32_t cmos_mm_readl (void *opaque, target_phys_addr_t addr)
528
{
529
    RTCState *s = opaque;
530
    uint32_t val;
531

    
532
    val = cmos_ioport_read(s, addr >> s->it_shift);
533
#ifdef TARGET_WORDS_BIGENDIAN
534
    val = bswap32(val);
535
#endif
536
    return val;
537
}
538

    
539
static void cmos_mm_writel (void *opaque,
540
                            target_phys_addr_t addr, uint32_t value)
541
{
542
    RTCState *s = opaque;
543
#ifdef TARGET_WORDS_BIGENDIAN
544
    value = bswap32(value);
545
#endif
546
    cmos_ioport_write(s, addr >> s->it_shift, value);
547
}
548

    
549
static CPUReadMemoryFunc *rtc_mm_read[] = {
550
    &cmos_mm_readb,
551
    &cmos_mm_readw,
552
    &cmos_mm_readl,
553
};
554

    
555
static CPUWriteMemoryFunc *rtc_mm_write[] = {
556
    &cmos_mm_writeb,
557
    &cmos_mm_writew,
558
    &cmos_mm_writel,
559
};
560

    
561
RTCState *rtc_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq)
562
{
563
    RTCState *s;
564
    int io_memory;
565

    
566
    s = qemu_mallocz(sizeof(RTCState));
567
    if (!s)
568
        return NULL;
569

    
570
    s->irq = irq;
571
    s->cmos_data[RTC_REG_A] = 0x26;
572
    s->cmos_data[RTC_REG_B] = 0x02;
573
    s->cmos_data[RTC_REG_C] = 0x00;
574
    s->cmos_data[RTC_REG_D] = 0x80;
575

    
576
    rtc_set_date_from_host(s);
577

    
578
    s->periodic_timer = qemu_new_timer(vm_clock,
579
                                       rtc_periodic_timer, s);
580
    s->second_timer = qemu_new_timer(vm_clock,
581
                                     rtc_update_second, s);
582
    s->second_timer2 = qemu_new_timer(vm_clock,
583
                                      rtc_update_second2, s);
584

    
585
    s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
586
    qemu_mod_timer(s->second_timer2, s->next_second_time);
587

    
588
    io_memory = cpu_register_io_memory(0, rtc_mm_read, rtc_mm_write, s);
589
    cpu_register_physical_memory(base, 2 << it_shift, io_memory);
590

    
591
    register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
592
    return s;
593
}