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