(linenum→info "unix/slp.c:2238")

qemu/0.9.1/hw/mc146818rtc.c

    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:     target_phys_addr_t base;
   63:     int it_shift;
   64:     /* periodic timer */
   65:     QEMUTimer *periodic_timer;
   66:     int64_t next_periodic_time;
   67:     /* second update */
   68:     int64_t next_second_time;
   69:     QEMUTimer *second_timer;
   70:     QEMUTimer *second_timer2;
   71: };
   72: 
   73: static void rtc_set_time(RTCState *s);
   74: static void rtc_copy_date(RTCState *s);
   75: 
   76: static void rtc_timer_update(RTCState *s, int64_t current_time)
   77: {
   78:     int period_code, period;
   79:     int64_t cur_clock, next_irq_clock;
   80: 
   81:     period_code = s->cmos_data[RTC_REG_A] & 0x0f;
   82:     if (period_code != 0 &&
   83:         (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
   84:         if (period_code <= 2)
   85:             period_code += 7;
   86:         /* period in 32 Khz cycles */
   87:         period = 1 << (period_code - 1);
   88:         /* compute 32 khz clock */
   89:         cur_clock = muldiv64(current_time, 32768, ticks_per_sec);
   90:         next_irq_clock = (cur_clock & ~(period - 1)) + period;
   91:         s->next_periodic_time = muldiv64(next_irq_clock, ticks_per_sec, 32768) + 1;
   92:         qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
   93:     } else {
   94:         qemu_del_timer(s->periodic_timer);
   95:     }
   96: }
   97: 
   98: static void rtc_periodic_timer(void *opaque)
   99: {
  100:     RTCState *s = opaque;
  101: 
  102:     rtc_timer_update(s, s->next_periodic_time);
  103:     s->cmos_data[RTC_REG_C] |= 0xc0;
  104:     qemu_irq_raise(s->irq);
  105: }
  106: 
  107: static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
  108: {
  109:     RTCState *s = opaque;
  110: 
  111:     if ((addr & 1) == 0) {
  112:         s->cmos_index = data & 0x7f;
  113:     } else {
  114: #ifdef DEBUG_CMOS
  115:         printf("cmos: write index=0x%02x val=0x%02x\n",
  116:                s->cmos_index, data);
  117: #endif
  118:         switch(s->cmos_index) {
  119:         case RTC_SECONDS_ALARM:
  120:         case RTC_MINUTES_ALARM:
  121:         case RTC_HOURS_ALARM:
  122:             /* XXX: not supported */
  123:             s->cmos_data[s->cmos_index] = data;
  124:             break;
  125:         case RTC_SECONDS:
  126:         case RTC_MINUTES:
  127:         case RTC_HOURS:
  128:         case RTC_DAY_OF_WEEK:
  129:         case RTC_DAY_OF_MONTH:
  130:         case RTC_MONTH:
  131:         case RTC_YEAR:
  132:             s->cmos_data[s->cmos_index] = data;
  133:             /* if in set mode, do not update the time */
  134:             if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
  135:                 rtc_set_time(s);
  136:             }
  137:             break;
  138:         case RTC_REG_A:
  139:             /* UIP bit is read only */
  140:             s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
  141:                 (s->cmos_data[RTC_REG_A] & REG_A_UIP);
  142:             rtc_timer_update(s, qemu_get_clock(vm_clock));
  143:             break;
  144:         case RTC_REG_B:
  145:             if (data & REG_B_SET) {
  146:                 /* set mode: reset UIP mode */
  147:                 s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
  148:                 data &= ~REG_B_UIE;
  149:             } else {
  150:                 /* if disabling set mode, update the time */
  151:                 if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
  152:                     rtc_set_time(s);
  153:                 }
  154:             }
  155:             s->cmos_data[RTC_REG_B] = data;
  156:             rtc_timer_update(s, qemu_get_clock(vm_clock));
  157:             break;
  158:         case RTC_REG_C:
  159:         case RTC_REG_D:
  160:             /* cannot write to them */
  161:             break;
  162:         default:
  163:             s->cmos_data[s->cmos_index] = data;
  164:             break;
  165:         }
  166:     }
  167: }
  168: 
  169: static inline int to_bcd(RTCState *s, int a)
  170: {
  171:     if (s->cmos_data[RTC_REG_B] & 0x04) {
  172:         return a;
  173:     } else {
  174:         return ((a / 10) << 4) | (a % 10);
  175:     }
  176: }
  177: 
  178: static inline int from_bcd(RTCState *s, int a)
  179: {
  180:     if (s->cmos_data[RTC_REG_B] & 0x04) {
  181:         return a;
  182:     } else {
  183:         return ((a >> 4) * 10) + (a & 0x0f);
  184:     }
  185: }
  186: 
  187: static void rtc_set_time(RTCState *s)
  188: {
  189:     struct tm *tm = &s->current_tm;
  190: 
  191:     tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]);
  192:     tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]);
  193:     tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
  194:     if (!(s->cmos_data[RTC_REG_B] & 0x02) &&
  195:         (s->cmos_data[RTC_HOURS] & 0x80)) {
  196:         tm->tm_hour += 12;
  197:     }
  198:     tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]);
  199:     tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
  200:     tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
  201:     tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + 100;
  202: }
  203: 
  204: static void rtc_copy_date(RTCState *s)
  205: {
  206:     const struct tm *tm = &s->current_tm;
  207: 
  208:     s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
  209:     s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
  210:     if (s->cmos_data[RTC_REG_B] & 0x02) {
  211:         /* 24 hour format */
  212:         s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour);
  213:     } else {
  214:         /* 12 hour format */
  215:         s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12);
  216:         if (tm->tm_hour >= 12)
  217:             s->cmos_data[RTC_HOURS] |= 0x80;
  218:     }
  219:     s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday);
  220:     s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday);
  221:     s->cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1);
  222:     s->cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100);
  223: }
  224: 
  225: /* month is between 0 and 11. */
  226: static int get_days_in_month(int month, int year)
  227: {
  228:     static const int days_tab[12] = {
  229:         31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  230:     };
  231:     int d;
  232:     if ((unsigned )month >= 12)
  233:         return 31;
  234:     d = days_tab[month];
  235:     if (month == 1) {
  236:         if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
  237:             d++;
  238:     }
  239:     return d;
  240: }
  241: 
  242: /* update 'tm' to the next second */
  243: static void rtc_next_second(struct tm *tm)
  244: {
  245:     int days_in_month;
  246: 
  247:     tm->tm_sec++;
  248:     if ((unsigned)tm->tm_sec >= 60) {
  249:         tm->tm_sec = 0;
  250:         tm->tm_min++;
  251:         if ((unsigned)tm->tm_min >= 60) {
  252:             tm->tm_min = 0;
  253:             tm->tm_hour++;
  254:             if ((unsigned)tm->tm_hour >= 24) {
  255:                 tm->tm_hour = 0;
  256:                 /* next day */
  257:                 tm->tm_wday++;
  258:                 if ((unsigned)tm->tm_wday >= 7)
  259:                     tm->tm_wday = 0;
  260:                 days_in_month = get_days_in_month(tm->tm_mon,
  261:                                                   tm->tm_year + 1900);
  262:                 tm->tm_mday++;
  263:                 if (tm->tm_mday < 1) {
  264:                     tm->tm_mday = 1;
  265:                 } else if (tm->tm_mday > days_in_month) {
  266:                     tm->tm_mday = 1;
  267:                     tm->tm_mon++;
  268:                     if (tm->tm_mon >= 12) {
  269:                         tm->tm_mon = 0;
  270:                         tm->tm_year++;
  271:                     }
  272:                 }
  273:             }
  274:         }
  275:     }
  276: }
  277: 
  278: 
  279: static void rtc_update_second(void *opaque)
  280: {
  281:     RTCState *s = opaque;
  282:     int64_t delay;
  283: 
  284:     /* if the oscillator is not in normal operation, we do not update */
  285:     if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
  286:         s->next_second_time += ticks_per_sec;
  287:         qemu_mod_timer(s->second_timer, s->next_second_time);
  288:     } else {
  289:         rtc_next_second(&s->current_tm);
  290: 
  291:         if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
  292:             /* update in progress bit */
  293:             s->cmos_data[RTC_REG_A] |= REG_A_UIP;
  294:         }
  295:         /* should be 244 us = 8 / 32768 seconds, but currently the
  296:            timers do not have the necessary resolution. */
  297:         delay = (ticks_per_sec * 1) / 100;
  298:         if (delay < 1)
  299:             delay = 1;
  300:         qemu_mod_timer(s->second_timer2,
  301:                        s->next_second_time + delay);
  302:     }
  303: }
  304: 
  305: static void rtc_update_second2(void *opaque)
  306: {
  307:     RTCState *s = opaque;
  308: 
  309:     if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
  310:         rtc_copy_date(s);
  311:     }
  312: 
  313:     /* check alarm */
  314:     if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
  315:         if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
  316:              s->cmos_data[RTC_SECONDS_ALARM] == s->current_tm.tm_sec) &&
  317:             ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
  318:              s->cmos_data[RTC_MINUTES_ALARM] == s->current_tm.tm_mon) &&
  319:             ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
  320:              s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) {
  321: 
  322:             s->cmos_data[RTC_REG_C] |= 0xa0;
  323:             qemu_irq_raise(s->irq);
  324:         }
  325:     }
  326: 
  327:     /* update ended interrupt */
  328:     if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
  329:         s->cmos_data[RTC_REG_C] |= 0x90;
  330:         qemu_irq_raise(s->irq);
  331:     }
  332: 
  333:     /* clear update in progress bit */
  334:     s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
  335: 
  336:     s->next_second_time += ticks_per_sec;
  337:     qemu_mod_timer(s->second_timer, s->next_second_time);
  338: }
  339: 
  340: static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
  341: {
  342:     RTCState *s = opaque;
  343:     int ret;
  344:     if ((addr & 1) == 0) {
  345:         return 0xff;
  346:     } else {
  347:         switch(s->cmos_index) {
  348:         case RTC_SECONDS:
  349:         case RTC_MINUTES:
  350:         case RTC_HOURS:
  351:         case RTC_DAY_OF_WEEK:
  352:         case RTC_DAY_OF_MONTH:
  353:         case RTC_MONTH:
  354:         case RTC_YEAR:
  355:             ret = s->cmos_data[s->cmos_index];
  356:             break;
  357:         case RTC_REG_A:
  358:             ret = s->cmos_data[s->cmos_index];
  359:             break;
  360:         case RTC_REG_C:
  361:             ret = s->cmos_data[s->cmos_index];
  362:             qemu_irq_lower(s->irq);
  363:             s->cmos_data[RTC_REG_C] = 0x00;
  364:             break;
  365:         default:
  366:             ret = s->cmos_data[s->cmos_index];
  367:             break;
  368:         }
  369: #ifdef DEBUG_CMOS
  370:         printf("cmos: read index=0x%02x val=0x%02x\n",
  371:                s->cmos_index, ret);
  372: #endif
  373:         return ret;
  374:     }
  375: }
  376: 
  377: void rtc_set_memory(RTCState *s, int addr, int val)
  378: {
  379:     if (addr >= 0 && addr <= 127)
  380:         s->cmos_data[addr] = val;
  381: }
  382: 
  383: void rtc_set_date(RTCState *s, const struct tm *tm)
  384: {
  385:     s->current_tm = *tm;
  386:     rtc_copy_date(s);
  387: }
  388: 
  389: /* PC cmos mappings */
  390: #define REG_IBM_CENTURY_BYTE        0x32
  391: #define REG_IBM_PS2_CENTURY_BYTE    0x37
  392: 
  393: static void rtc_set_date_from_host(RTCState *s)
  394: {
  395:     time_t ti;
  396:     struct tm *tm;
  397:     int val;
  398: 
  399:     /* set the CMOS date */
  400:     if (rtc_start_date == -1) {
  401:         time(&ti);
  402:         if (rtc_utc)
  403:             tm = gmtime(&ti);
  404:         else
  405:             tm = localtime(&ti);
  406:     } else {
  407:         ti = rtc_start_date;
  408:         tm = gmtime(&ti);
  409:     }
  410:     rtc_set_date(s, tm);
  411: 
  412:     val = to_bcd(s, (tm->tm_year / 100) + 19);
  413:     rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
  414:     rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
  415: }
  416: 
  417: static void rtc_save(QEMUFile *f, void *opaque)
  418: {
  419:     RTCState *s = opaque;
  420: 
  421:     qemu_put_buffer(f, s->cmos_data, 128);
  422:     qemu_put_8s(f, &s->cmos_index);
  423: 
  424:     qemu_put_be32(f, s->current_tm.tm_sec);
  425:     qemu_put_be32(f, s->current_tm.tm_min);
  426:     qemu_put_be32(f, s->current_tm.tm_hour);
  427:     qemu_put_be32(f, s->current_tm.tm_wday);
  428:     qemu_put_be32(f, s->current_tm.tm_mday);
  429:     qemu_put_be32(f, s->current_tm.tm_mon);
  430:     qemu_put_be32(f, s->current_tm.tm_year);
  431: 
  432:     qemu_put_timer(f, s->periodic_timer);
  433:     qemu_put_be64(f, s->next_periodic_time);
  434: 
  435:     qemu_put_be64(f, s->next_second_time);
  436:     qemu_put_timer(f, s->second_timer);
  437:     qemu_put_timer(f, s->second_timer2);
  438: }
  439: 
  440: static int rtc_load(QEMUFile *f, void *opaque, int version_id)
  441: {
  442:     RTCState *s = opaque;
  443: 
  444:     if (version_id != 1)
  445:         return -EINVAL;
  446: 
  447:     qemu_get_buffer(f, s->cmos_data, 128);
  448:     qemu_get_8s(f, &s->cmos_index);
  449: 
  450:     s->current_tm.tm_sec=qemu_get_be32(f);
  451:     s->current_tm.tm_min=qemu_get_be32(f);
  452:     s->current_tm.tm_hour=qemu_get_be32(f);
  453:     s->current_tm.tm_wday=qemu_get_be32(f);
  454:     s->current_tm.tm_mday=qemu_get_be32(f);
  455:     s->current_tm.tm_mon=qemu_get_be32(f);
  456:     s->current_tm.tm_year=qemu_get_be32(f);
  457: 
  458:     qemu_get_timer(f, s->periodic_timer);
  459:     s->next_periodic_time=qemu_get_be64(f);
  460: 
  461:     s->next_second_time=qemu_get_be64(f);
  462:     qemu_get_timer(f, s->second_timer);
  463:     qemu_get_timer(f, s->second_timer2);
  464:     return 0;
  465: }
  466: 
  467: RTCState *rtc_init(int base, qemu_irq irq)
  468: {
  469:     RTCState *s;
  470: 
  471:     s = qemu_mallocz(sizeof(RTCState));
  472:     if (!s)
  473:         return NULL;
  474: 
  475:     s->irq = irq;
  476:     s->cmos_data[RTC_REG_A] = 0x26;
  477:     s->cmos_data[RTC_REG_B] = 0x02;
  478:     s->cmos_data[RTC_REG_C] = 0x00;
  479:     s->cmos_data[RTC_REG_D] = 0x80;
  480: 
  481:     rtc_set_date_from_host(s);
  482: 
  483:     s->periodic_timer = qemu_new_timer(vm_clock,
  484:                                        rtc_periodic_timer, s);
  485:     s->second_timer = qemu_new_timer(vm_clock,
  486:                                      rtc_update_second, s);
  487:     s->second_timer2 = qemu_new_timer(vm_clock,
  488:                                       rtc_update_second2, s);
  489: 
  490:     s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
  491:     qemu_mod_timer(s->second_timer2, s->next_second_time);
  492: 
  493:     register_ioport_write(base, 2, 1, cmos_ioport_write, s);
  494:     register_ioport_read(base, 2, 1, cmos_ioport_read, s);
  495: 
  496:     register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
  497:     return s;
  498: }
  499: 
  500: /* Memory mapped interface */
  501: static uint32_t cmos_mm_readb (void *opaque, target_phys_addr_t addr)
  502: {
  503:     RTCState *s = opaque;
  504: 
  505:     return cmos_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFF;
  506: }
  507: 
  508: static void cmos_mm_writeb (void *opaque,
  509:                             target_phys_addr_t addr, uint32_t value)
  510: {
  511:     RTCState *s = opaque;
  512: 
  513:     cmos_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFF);
  514: }
  515: 
  516: static uint32_t cmos_mm_readw (void *opaque, target_phys_addr_t addr)
  517: {
  518:     RTCState *s = opaque;
  519:     uint32_t val;
  520: 
  521:     val = cmos_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
  522: #ifdef TARGET_WORDS_BIGENDIAN
  523:     val = bswap16(val);
  524: #endif
  525:     return val;
  526: }
  527: 
  528: static void cmos_mm_writew (void *opaque,
  529:                             target_phys_addr_t addr, uint32_t value)
  530: {
  531:     RTCState *s = opaque;
  532: #ifdef TARGET_WORDS_BIGENDIAN
  533:     value = bswap16(value);
  534: #endif
  535:     cmos_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFFFF);
  536: }
  537: 
  538: static uint32_t cmos_mm_readl (void *opaque, target_phys_addr_t addr)
  539: {
  540:     RTCState *s = opaque;
  541:     uint32_t val;
  542: 
  543:     val = cmos_ioport_read(s, (addr - s->base) >> s->it_shift);
  544: #ifdef TARGET_WORDS_BIGENDIAN
  545:     val = bswap32(val);
  546: #endif
  547:     return