qemu/hw/mc146818rtc.c
<<
>>
Prefs
   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#include "hpet_emul.h"
  30
  31//#define DEBUG_CMOS
  32
  33#define RTC_SECONDS             0
  34#define RTC_SECONDS_ALARM       1
  35#define RTC_MINUTES             2
  36#define RTC_MINUTES_ALARM       3
  37#define RTC_HOURS               4
  38#define RTC_HOURS_ALARM         5
  39#define RTC_ALARM_DONT_CARE    0xC0
  40
  41#define RTC_DAY_OF_WEEK         6
  42#define RTC_DAY_OF_MONTH        7
  43#define RTC_MONTH               8
  44#define RTC_YEAR                9
  45
  46#define RTC_REG_A               10
  47#define RTC_REG_B               11
  48#define RTC_REG_C               12
  49#define RTC_REG_D               13
  50
  51#define REG_A_UIP 0x80
  52
  53#define REG_B_SET  0x80
  54#define REG_B_PIE  0x40
  55#define REG_B_AIE  0x20
  56#define REG_B_UIE  0x10
  57#define REG_B_SQWE 0x08
  58#define REG_B_DM   0x04
  59
  60#define REG_C_UF   0x10
  61#define REG_C_IRQF 0x80
  62#define REG_C_PF   0x40
  63#define REG_C_AF   0x20
  64
  65struct RTCState {
  66    uint8_t cmos_data[128];
  67    uint8_t cmos_index;
  68    struct tm current_tm;
  69    int base_year;
  70    qemu_irq irq;
  71    qemu_irq sqw_irq;
  72    int it_shift;
  73    /* periodic timer */
  74    QEMUTimer *periodic_timer;
  75    int64_t next_periodic_time;
  76    /* second update */
  77    int64_t next_second_time;
  78#ifdef TARGET_I386
  79    uint32_t irq_coalesced;
  80    uint32_t period;
  81    QEMUTimer *coalesced_timer;
  82#endif
  83    QEMUTimer *second_timer;
  84    QEMUTimer *second_timer2;
  85};
  86
  87static void rtc_irq_raise(qemu_irq irq) {
  88    /* When HPET is operating in legacy mode, RTC interrupts are disabled
  89     * We block qemu_irq_raise, but not qemu_irq_lower, in case legacy
  90     * mode is established while interrupt is raised. We want it to
  91     * be lowered in any case
  92     */
  93#if defined TARGET_I386 || defined TARGET_X86_64
  94    if (!hpet_in_legacy_mode())
  95#endif
  96        qemu_irq_raise(irq);
  97}
  98
  99static void rtc_set_time(RTCState *s);
 100static void rtc_copy_date(RTCState *s);
 101
 102#ifdef TARGET_I386
 103static void rtc_coalesced_timer_update(RTCState *s)
 104{
 105    if (s->irq_coalesced == 0) {
 106        qemu_del_timer(s->coalesced_timer);
 107    } else {
 108        /* divide each RTC interval to 2 - 8 smaller intervals */
 109        int c = MIN(s->irq_coalesced, 7) + 1; 
 110        int64_t next_clock = qemu_get_clock(vm_clock) +
 111                muldiv64(s->period / c, ticks_per_sec, 32768);
 112        qemu_mod_timer(s->coalesced_timer, next_clock);
 113    }
 114}
 115
 116static void rtc_coalesced_timer(void *opaque)
 117{
 118    RTCState *s = opaque;
 119
 120    if (s->irq_coalesced != 0) {
 121        apic_reset_irq_delivered();
 122        s->cmos_data[RTC_REG_C] |= 0xc0;
 123        rtc_irq_raise(s->irq);
 124        if (apic_get_irq_delivered()) {
 125            s->irq_coalesced--;
 126        }
 127    }
 128
 129    rtc_coalesced_timer_update(s);
 130}
 131#endif
 132
 133static void rtc_timer_update(RTCState *s, int64_t current_time)
 134{
 135    int period_code, period;
 136    int64_t cur_clock, next_irq_clock;
 137    int enable_pie;
 138
 139    period_code = s->cmos_data[RTC_REG_A] & 0x0f;
 140#if defined TARGET_I386 || defined TARGET_X86_64
 141    /* disable periodic timer if hpet is in legacy mode, since interrupts are
 142     * disabled anyway.
 143     */
 144    enable_pie = !hpet_in_legacy_mode();
 145#else
 146    enable_pie = 1;
 147#endif
 148    if (period_code != 0
 149        && (((s->cmos_data[RTC_REG_B] & REG_B_PIE) && enable_pie)
 150            || ((s->cmos_data[RTC_REG_B] & REG_B_SQWE) && s->sqw_irq))) {
 151        if (period_code <= 2)
 152            period_code += 7;
 153        /* period in 32 Khz cycles */
 154        period = 1 << (period_code - 1);
 155#ifdef TARGET_I386
 156        if(period != s->period)
 157            s->irq_coalesced = (s->irq_coalesced * s->period) / period;
 158        s->period = period;
 159#endif
 160        /* compute 32 khz clock */
 161        cur_clock = muldiv64(current_time, 32768, ticks_per_sec);
 162        next_irq_clock = (cur_clock & ~(period - 1)) + period;
 163        s->next_periodic_time = muldiv64(next_irq_clock, ticks_per_sec, 32768) + 1;
 164        qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
 165    } else {
 166#ifdef TARGET_I386
 167        s->irq_coalesced = 0;
 168#endif
 169        qemu_del_timer(s->periodic_timer);
 170    }
 171}
 172
 173static void rtc_periodic_timer(void *opaque)
 174{
 175    RTCState *s = opaque;
 176
 177    rtc_timer_update(s, s->next_periodic_time);
 178    if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
 179        s->cmos_data[RTC_REG_C] |= 0xc0;
 180#ifdef TARGET_I386
 181        if(rtc_td_hack) {
 182            apic_reset_irq_delivered();
 183            rtc_irq_raise(s->irq);
 184            if (!apic_get_irq_delivered()) {
 185                s->irq_coalesced++;
 186                rtc_coalesced_timer_update(s);
 187            }
 188        } else
 189#endif
 190        rtc_irq_raise(s->irq);
 191    }
 192    if (s->cmos_data[RTC_REG_B] & REG_B_SQWE) {
 193        /* Not square wave at all but we don't want 2048Hz interrupts!
 194           Must be seen as a pulse.  */
 195        qemu_irq_raise(s->sqw_irq);
 196    }
 197}
 198
 199static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
 200{
 201    RTCState *s = opaque;
 202
 203    if ((addr & 1) == 0) {
 204        s->cmos_index = data & 0x7f;
 205    } else {
 206#ifdef DEBUG_CMOS
 207        printf("cmos: write index=0x%02x val=0x%02x\n",
 208               s->cmos_index, data);
 209#endif
 210        switch(s->cmos_index) {
 211        case RTC_SECONDS_ALARM:
 212        case RTC_MINUTES_ALARM:
 213        case RTC_HOURS_ALARM:
 214            /* XXX: not supported */
 215            s->cmos_data[s->cmos_index] = data;
 216            break;
 217        case RTC_SECONDS:
 218        case RTC_MINUTES:
 219        case RTC_HOURS:
 220        case RTC_DAY_OF_WEEK:
 221        case RTC_DAY_OF_MONTH:
 222        case RTC_MONTH:
 223        case RTC_YEAR:
 224            s->cmos_data[s->cmos_index] = data;
 225            /* if in set mode, do not update the time */
 226            if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
 227                rtc_set_time(s);
 228            }
 229            break;
 230        case RTC_REG_A:
 231            /* UIP bit is read only */
 232            s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
 233                (s->cmos_data[RTC_REG_A] & REG_A_UIP);
 234            rtc_timer_update(s, qemu_get_clock(vm_clock));
 235            break;
 236        case RTC_REG_B:
 237            if (data & REG_B_SET) {
 238                /* set mode: reset UIP mode */
 239                s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
 240                data &= ~REG_B_UIE;
 241            } else {
 242                /* if disabling set mode, update the time */
 243                if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
 244                    rtc_set_time(s);
 245                }
 246            }
 247            s->cmos_data[RTC_REG_B] = data;
 248            rtc_timer_update(s, qemu_get_clock(vm_clock));
 249            break;
 250        case RTC_REG_C:
 251        case RTC_REG_D:
 252            /* cannot write to them */
 253            break;
 254        default:
 255            s->cmos_data[s->cmos_index] = data;
 256            break;
 257        }
 258    }
 259}
 260
 261static inline int to_bcd(RTCState *s, int a)
 262{
 263    if (s->cmos_data[RTC_REG_B] & REG_B_DM) {
 264        return a;
 265    } else {
 266        return ((a / 10) << 4) | (a % 10);
 267    }
 268}
 269
 270static inline int from_bcd(RTCState *s, int a)
 271{
 272    if (s->cmos_data[RTC_REG_B] & REG_B_DM) {
 273        return a;
 274    } else {
 275        return ((a >> 4) * 10) + (a & 0x0f);
 276    }
 277}
 278
 279static void rtc_set_time(RTCState *s)
 280{
 281    struct tm *tm = &s->current_tm;
 282
 283    tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]);
 284    tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]);
 285    tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
 286    if (!(s->cmos_data[RTC_REG_B] & 0x02) &&
 287        (s->cmos_data[RTC_HOURS] & 0x80)) {
 288        tm->tm_hour += 12;
 289    }
 290    tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]) - 1;
 291    tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
 292    tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
 293    tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + s->base_year - 1900;
 294}
 295
 296static void rtc_copy_date(RTCState *s)
 297{
 298    const struct tm *tm = &s->current_tm;
 299    int year;
 300
 301    s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
 302    s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
 303    if (s->cmos_data[RTC_REG_B] & 0x02) {
 304        /* 24 hour format */
 305        s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour);
 306    } else {
 307        /* 12 hour format */
 308        s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12);
 309        if (tm->tm_hour >= 12)
 310            s->cmos_data[RTC_HOURS] |= 0x80;
 311    }
 312    s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday + 1);
 313    s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday);
 314    s->cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1);
 315    year = (tm->tm_year - s->base_year) % 100;
 316    if (year < 0)
 317        year += 100;
 318    s->cmos_data[RTC_YEAR] = to_bcd(s, year);
 319}
 320
 321/* month is between 0 and 11. */
 322static int get_days_in_month(int month, int year)
 323{
 324    static const int days_tab[12] = {
 325        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
 326    };
 327    int d;
 328    if ((unsigned )month >= 12)
 329        return 31;
 330    d = days_tab[month];
 331    if (month == 1) {
 332        if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
 333            d++;
 334    }
 335    return d;
 336}
 337
 338/* update 'tm' to the next second */
 339static void rtc_next_second(struct tm *tm)
 340{
 341    int days_in_month;
 342
 343    tm->tm_sec++;
 344    if ((unsigned)tm->tm_sec >= 60) {
 345        tm->tm_sec = 0;
 346        tm->tm_min++;
 347        if ((unsigned)tm->tm_min >= 60) {
 348            tm->tm_min = 0;
 349            tm->tm_hour++;
 350            if ((unsigned)tm->tm_hour >= 24) {
 351                tm->tm_hour = 0;
 352                /* next day */
 353                tm->tm_wday++;
 354                if ((unsigned)tm->tm_wday >= 7)
 355                    tm->tm_wday = 0;
 356                days_in_month = get_days_in_month(tm->tm_mon,
 357                                                  tm->tm_year + 1900);
 358                tm->tm_mday++;
 359                if (tm->tm_mday < 1) {
 360                    tm->tm_mday = 1;
 361                } else if (tm->tm_mday > days_in_month) {
 362                    tm->tm_mday = 1;
 363                    tm->tm_mon++;
 364                    if (tm->tm_mon >= 12) {
 365                        tm->tm_mon = 0;
 366                        tm->tm_year++;
 367                    }
 368                }
 369            }
 370        }
 371    }
 372}
 373
 374
 375static void rtc_update_second(void *opaque)
 376{
 377    RTCState *s = opaque;
 378    int64_t delay;
 379
 380    /* if the oscillator is not in normal operation, we do not update */
 381    if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
 382        s->next_second_time += ticks_per_sec;
 383        qemu_mod_timer(s->second_timer, s->next_second_time);
 384    } else {
 385        rtc_next_second(&s->current_tm);
 386
 387        if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
 388            /* update in progress bit */
 389            s->cmos_data[RTC_REG_A] |= REG_A_UIP;
 390        }
 391        /* should be 244 us = 8 / 32768 seconds, but currently the
 392           timers do not have the necessary resolution. */
 393        delay = (ticks_per_sec * 1) / 100;
 394        if (delay < 1)
 395            delay = 1;
 396        qemu_mod_timer(s->second_timer2,
 397                       s->next_second_time + delay);
 398    }
 399}
 400
 401static void rtc_update_second2(void *opaque)
 402{
 403    RTCState *s = opaque;
 404
 405    if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
 406        rtc_copy_date(s);
 407    }
 408
 409    /* check alarm */
 410    if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
 411        if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
 412             s->cmos_data[RTC_SECONDS_ALARM] == s->current_tm.tm_sec) &&
 413            ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
 414             s->cmos_data[RTC_MINUTES_ALARM] == s->current_tm.tm_mon) &&
 415            ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
 416             s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) {
 417
 418            s->cmos_data[RTC_REG_C] |= 0xa0;
 419            rtc_irq_raise(s->irq);
 420        }
 421    }
 422
 423    /* update ended interrupt */
 424    s->cmos_data[RTC_REG_C] |= REG_C_UF;
 425    if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
 426      s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
 427      rtc_irq_raise(s->irq);
 428    }
 429
 430    /* clear update in progress bit */
 431    s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
 432
 433    s->next_second_time += ticks_per_sec;
 434    qemu_mod_timer(s->second_timer, s->next_second_time);
 435}
 436
 437static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
 438{
 439    RTCState *s = opaque;
 440    int ret;
 441    if ((addr & 1) == 0) {
 442        return 0xff;
 443    } else {
 444        switch(s->cmos_index) {
 445        case RTC_SECONDS:
 446        case RTC_MINUTES:
 447        case RTC_HOURS:
 448        case RTC_DAY_OF_WEEK:
 449        case RTC_DAY_OF_MONTH:
 450        case RTC_MONTH:
 451        case RTC_YEAR:
 452            ret = s->cmos_data[s->cmos_index];
 453            break;
 454        case RTC_REG_A:
 455            ret = s->cmos_data[s->cmos_index];
 456            break;
 457        case RTC_REG_C:
 458            ret = s->cmos_data[s->cmos_index];
 459            qemu_irq_lower(s->irq);
 460            s->cmos_data[RTC_REG_C] = 0x00;
 461            break;
 462        default:
 463            ret = s->cmos_data[s->cmos_index];
 464            break;
 465        }
 466#ifdef DEBUG_CMOS
 467        printf("cmos: read index=0x%02x val=0x%02x\n",
 468               s->cmos_index, ret);
 469#endif
 470        return ret;
 471    }
 472}
 473
 474void rtc_set_memory(RTCState *s, int addr, int val)
 475{
 476    if (addr >= 0 && addr <= 127)
 477        s->cmos_data[addr] = val;
 478}
 479
 480void rtc_set_date(RTCState *s, const struct tm *tm)
 481{
 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
 490static void rtc_set_date_from_host(RTCState *s)
 491{
 492    struct tm tm;
 493    int val;
 494
 495    /* set the CMOS date */
 496    qemu_get_timedate(&tm, 0);
 497    rtc_set_date(s, &tm);
 498
 499    val = to_bcd(s, (tm.tm_year / 100) + 19);
 500    rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
 501    rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
 502}
 503
 504static void rtc_save(QEMUFile *f, void *opaque)
 505{
 506    RTCState *s = opaque;
 507
 508    qemu_put_buffer(f, s->cmos_data, 128);
 509    qemu_put_8s(f, &s->cmos_index);
 510
 511    qemu_put_be32(f, s->current_tm.tm_sec);
 512    qemu_put_be32(f, s->current_tm.tm_min);
 513    qemu_put_be32(f, s->current_tm.tm_hour);
 514    qemu_put_be32(f, s->current_tm.tm_wday);
 515    qemu_put_be32(f, s->current_tm.tm_mday);
 516    qemu_put_be32(f, s->current_tm.tm_mon);
 517    qemu_put_be32(f, s->current_tm.tm_year);
 518
 519    qemu_put_timer(f, s->periodic_timer);
 520    qemu_put_be64(f, s->next_periodic_time);
 521
 522    qemu_put_be64(f, s->next_second_time);
 523    qemu_put_timer(f, s->second_timer);
 524    qemu_put_timer(f, s->second_timer2);
 525}
 526
 527static int rtc_load(QEMUFile *f, void *opaque, int version_id)
 528{
 529    RTCState *s = opaque;
 530
 531    if (version_id != 1)
 532        return -EINVAL;
 533
 534    qemu_get_buffer(f, s->cmos_data, 128);
 535    qemu_get_8s(f, &s->cmos_index);
 536
 537    s->current_tm.tm_sec=qemu_get_be32(f);
 538    s->current_tm.tm_min=qemu_get_be32(f);
 539    s->current_tm.tm_hour=qemu_get_be32(f);
 540    s->current_tm.tm_wday=qemu_get_be32(f);
 541    s->current_tm.tm_mday=qemu_get_be32(f);
 542    s->current_tm.tm_mon=qemu_get_be32(f);
 543    s->current_tm.tm_year=qemu_get_be32(f);
 544
 545    qemu_get_timer(f, s->periodic_timer);
 546    s->next_periodic_time=qemu_get_be64(f);
 547
 548    s->next_second_time=qemu_get_be64(f);
 549    qemu_get_timer(f, s->second_timer);
 550    qemu_get_timer(f, s->second_timer2);
 551    return 0;
 552}
 553
 554#ifdef TARGET_I386
 555static void rtc_save_td(QEMUFile *f, void *opaque)
 556{
 557    RTCState *s = opaque;
 558
 559    qemu_put_be32(f, s->irq_coalesced);
 560    qemu_put_be32(f, s->period);
 561}
 562
 563static int rtc_load_td(QEMUFile *f, void *opaque, int version_id)
 564{
 565    RTCState *s = opaque;
 566
 567    if (version_id != 1)
 568        return -EINVAL;
 569
 570    s->irq_coalesced = qemu_get_be32(f);
 571    s->period = qemu_get_be32(f);
 572    rtc_coalesced_timer_update(s);
 573    return 0;
 574}
 575#endif
 576
 577static void rtc_reset(void *opaque)
 578{
 579    RTCState *s = opaque;
 580
 581    s->cmos_data[RTC_REG_B] &= ~(REG_B_PIE | REG_B_AIE | REG_B_SQWE);
 582    s->cmos_data[RTC_REG_C] &= ~(REG_C_UF | REG_C_IRQF | REG_C_PF | REG_C_AF);
 583
 584    qemu_irq_lower(s->irq);
 585
 586#ifdef TARGET_I386
 587    if (rtc_td_hack)
 588            s->irq_coalesced = 0;
 589#endif
 590}
 591
 592RTCState *rtc_init_sqw(int base, qemu_irq irq, qemu_irq sqw_irq, int base_year)
 593{
 594    RTCState *s;
 595
 596    s = qemu_mallocz(sizeof(RTCState));
 597
 598    s->irq = irq;
 599    s->sqw_irq = sqw_irq;
 600    s->cmos_data[RTC_REG_A] = 0x26;
 601    s->cmos_data[RTC_REG_B] = 0x02;
 602    s->cmos_data[RTC_REG_C] = 0x00;
 603    s->cmos_data[RTC_REG_D] = 0x80;
 604
 605    s->base_year = base_year;
 606    rtc_set_date_from_host(s);
 607
 608    s->periodic_timer = qemu_new_timer(vm_clock,
 609                                       rtc_periodic_timer, s);
 610#ifdef TARGET_I386
 611    if (rtc_td_hack)
 612        s->coalesced_timer = qemu_new_timer(vm_clock, rtc_coalesced_timer, s);
 613#endif
 614    s->second_timer = qemu_new_timer(vm_clock,
 615                                     rtc_update_second, s);
 616    s->second_timer2 = qemu_new_timer(vm_clock,
 617                                      rtc_update_second2, s);
 618
 619    s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
 620    qemu_mod_timer(s->second_timer2, s->next_second_time);
 621
 622    register_ioport_write(base, 2, 1, cmos_ioport_write, s);
 623    register_ioport_read(base, 2, 1, cmos_ioport_read, s);
 624
 625    register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
 626#ifdef TARGET_I386
 627    if (rtc_td_hack)
 628        register_savevm("mc146818rtc-td", base, 1, rtc_save_td, rtc_load_td, s);
 629#endif
 630    qemu_register_reset(rtc_reset, s);
 631
 632    return s;
 633}
 634
 635RTCState *rtc_init(int base, qemu_irq irq, int base_year)
 636{
 637    return rtc_init_sqw(base, irq, NULL, base_year);
 638}
 639
 640/* Memory mapped interface */
 641static uint32_t cmos_mm_readb (void *opaque, target_phys_addr_t addr)
 642{
 643    RTCState *s = opaque;
 644
 645    return cmos_ioport_read(s, addr >> s->it_shift) & 0xFF;
 646}
 647
 648static void cmos_mm_writeb (void *opaque,
 649                            target_phys_addr_t addr, uint32_t value)
 650{
 651    RTCState *s = opaque;
 652
 653    cmos_ioport_write(s, addr >> s->it_shift, value & 0xFF);
 654}
 655
 656static uint32_t cmos_mm_readw (void *opaque, target_phys_addr_t addr)
 657{
 658    RTCState *s = opaque;
 659    uint32_t val;
 660
 661    val = cmos_ioport_read(s, addr >> s->it_shift) & 0xFFFF;
 662#ifdef TARGET_WORDS_BIGENDIAN
 663    val = bswap16(val);
 664#endif
 665    return val;
 666}
 667
 668static void cmos_mm_writew (void *opaque,
 669                            target_phys_addr_t addr, uint32_t value)
 670{
 671    RTCState *s = opaque;
 672#ifdef TARGET_WORDS_BIGENDIAN
 673    value = bswap16(value);
 674#endif
 675    cmos_ioport_write(s, addr >> s->it_shift, value & 0xFFFF);
 676}
 677
 678static uint32_t cmos_mm_readl (void *opaque, target_phys_addr_t addr)
 679{
 680    RTCState *s = opaque;
 681    uint32_t val;
 682
 683    val = cmos_ioport_read(s, addr >> s->it_shift);
 684#ifdef TARGET_WORDS_BIGENDIAN
 685    val = bswap32(val);
 686#endif
 687    return val;
 688}
 689
 690static void cmos_mm_writel (void *opaque,
 691                            target_phys_addr_t addr, uint32_t value)
 692{
 693    RTCState *s = opaque;
 694#ifdef TARGET_WORDS_BIGENDIAN
 695    value = bswap32(value);
 696#endif
 697    cmos_ioport_write(s, addr >> s->it_shift, value);
 698}
 699
 700static CPUReadMemoryFunc *rtc_mm_read[] = {
 701    &cmos_mm_readb,
 702    &cmos_mm_readw,
 703    &cmos_mm_readl,
 704};
 705
 706static CPUWriteMemoryFunc *rtc_mm_write[] = {
 707    &cmos_mm_writeb,
 708    &cmos_mm_writew,
 709    &cmos_mm_writel,
 710};
 711
 712RTCState *rtc_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq,
 713                      int base_year)
 714{
 715    RTCState *s;
 716    int io_memory;
 717
 718    s = qemu_mallocz(sizeof(RTCState));
 719
 720    s->irq = irq;
 721    s->cmos_data[RTC_REG_A] = 0x26;
 722    s->cmos_data[RTC_REG_B] = 0x02;
 723    s->cmos_data[RTC_REG_C] = 0x00;
 724    s->cmos_data[RTC_REG_D] = 0x80;
 725
 726    s->base_year = base_year;
 727    rtc_set_date_from_host(s);
 728
 729    s->periodic_timer = qemu_new_timer(vm_clock,
 730                                       rtc_periodic_timer, s);
 731    s->second_timer = qemu_new_timer(vm_clock,
 732                                     rtc_update_second, s);
 733    s->second_timer2 = qemu_new_timer(vm_clock,
 734                                      rtc_update_second2, s);
 735
 736    s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
 737    qemu_mod_timer(s->second_timer2, s->next_second_time);
 738
 739    io_memory = cpu_register_io_memory(rtc_mm_read, rtc_mm_write, s);
 740    cpu_register_physical_memory(base, 2 << it_shift, io_memory);
 741
 742    register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
 743#ifdef TARGET_I386
 744    if (rtc_td_hack)
 745        register_savevm("mc146818rtc-td", base, 1, rtc_save_td, rtc_load_td, s);
 746#endif
 747    qemu_register_reset(rtc_reset, s);
 748    return s;
 749}
 750