Diff for /qemu/hw/m48t59.c between versions 1.1.1.4 and 1.1.1.5

version 1.1.1.4, 2018/04/24 16:48:27 version 1.1.1.5, 2018/04/24 16:52:41
Line 46  struct m48t59_t { Line 46  struct m48t59_t {
     /* Hardware parameters */      /* Hardware parameters */
     qemu_irq IRQ;      qemu_irq IRQ;
     int mem_index;      int mem_index;
     target_phys_addr_t mem_base;  
     uint32_t io_base;      uint32_t io_base;
     uint16_t size;      uint16_t size;
     /* RTC management */      /* RTC management */
     time_t   time_offset;      time_t   time_offset;
     time_t   stop_time;      time_t   stop_time;
     /* Alarm & watchdog */      /* Alarm & watchdog */
     time_t   alarm;      struct tm alarm;
     struct QEMUTimer *alrm_timer;      struct QEMUTimer *alrm_timer;
     struct QEMUTimer *wd_timer;      struct QEMUTimer *wd_timer;
     /* NVRAM storage */      /* NVRAM storage */
Line 74  static inline uint8_t fromBCD (uint8_t B Line 73  static inline uint8_t fromBCD (uint8_t B
     return ((BCD >> 4) * 10) + (BCD & 0x0F);      return ((BCD >> 4) * 10) + (BCD & 0x0F);
 }  }
   
 /* RTC management helpers */  
 static void get_time (m48t59_t *NVRAM, struct tm *tm)  
 {  
     time_t t;  
   
     t = time(NULL) + NVRAM->time_offset;  
 #ifdef _WIN32  
     memcpy(tm,localtime(&t),sizeof(*tm));  
 #else  
     if (rtc_utc)  
         gmtime_r (&t, tm);  
     else  
         localtime_r (&t, tm) ;  
 #endif  
 }  
   
 static void set_time (m48t59_t *NVRAM, struct tm *tm)  
 {  
     time_t now, new_time;  
   
     new_time = mktime(tm);  
     now = time(NULL);  
     NVRAM->time_offset = new_time - now;  
 }  
   
 /* Alarm management */  /* Alarm management */
 static void alarm_cb (void *opaque)  static void alarm_cb (void *opaque)
 {  {
     struct tm tm, tm_now;      struct tm tm;
     uint64_t next_time;      uint64_t next_time;
     m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
   
Line 111  static void alarm_cb (void *opaque) Line 85  static void alarm_cb (void *opaque)
         (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&          (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
         (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&          (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
         (NVRAM->buffer[0x1FF2] & 0x80) == 0) {          (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
         /* Repeat once a month */          /* Repeat once a month */
         get_time(NVRAM, &tm_now);          qemu_get_timedate(&tm, NVRAM->time_offset);
         memcpy(&tm, &tm_now, sizeof(struct tm));          tm.tm_mon++;
         tm.tm_mon++;          if (tm.tm_mon == 13) {
         if (tm.tm_mon == 13) {              tm.tm_mon = 1;
             tm.tm_mon = 1;              tm.tm_year++;
             tm.tm_year++;          }
         }          next_time = qemu_timedate_diff(&tm) - NVRAM->time_offset;
         next_time = mktime(&tm);  
     } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&      } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
                (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&                 (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
                (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&                 (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
                (NVRAM->buffer[0x1FF2] & 0x80) == 0) {                 (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
         /* Repeat once a day */          /* Repeat once a day */
         next_time = 24 * 60 * 60 + mktime(&tm_now);          next_time = 24 * 60 * 60;
     } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&      } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
                (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&                 (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
                (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&                 (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
                (NVRAM->buffer[0x1FF2] & 0x80) == 0) {                 (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
         /* Repeat once an hour */          /* Repeat once an hour */
         next_time = 60 * 60 + mktime(&tm_now);          next_time = 60 * 60;
     } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&      } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
                (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&                 (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
                (NVRAM->buffer[0x1FF3] & 0x80) != 0 &&                 (NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
                (NVRAM->buffer[0x1FF2] & 0x80) == 0) {                 (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
         /* Repeat once a minute */          /* Repeat once a minute */
         next_time = 60 + mktime(&tm_now);          next_time = 60;
     } else {      } else {
         /* Repeat once a second */          /* Repeat once a second */
         next_time = 1 + mktime(&tm_now);          next_time = 1;
     }      }
     qemu_mod_timer(NVRAM->alrm_timer, next_time * 1000);      qemu_mod_timer(NVRAM->alrm_timer, qemu_get_clock(vm_clock) +
                       next_time * 1000);
     qemu_set_irq(NVRAM->IRQ, 0);      qemu_set_irq(NVRAM->IRQ, 0);
 }  }
   
   static void set_alarm (m48t59_t *NVRAM)
   {
       int diff;
       if (NVRAM->alrm_timer != NULL) {
           qemu_del_timer(NVRAM->alrm_timer);
           diff = qemu_timedate_diff(&NVRAM->alarm) - NVRAM->time_offset;
           if (diff > 0)
               qemu_mod_timer(NVRAM->alrm_timer, diff * 1000);
       }
   }
   
 static void get_alarm (m48t59_t *NVRAM, struct tm *tm)  /* RTC management helpers */
   static inline void get_time (m48t59_t *NVRAM, struct tm *tm)
 {  {
 #ifdef _WIN32      qemu_get_timedate(tm, NVRAM->time_offset);
     memcpy(tm,localtime(&NVRAM->alarm),sizeof(*tm));  
 #else  
     if (rtc_utc)  
         gmtime_r (&NVRAM->alarm, tm);  
     else  
         localtime_r (&NVRAM->alarm, tm);  
 #endif  
 }  }
   
 static void set_alarm (m48t59_t *NVRAM, struct tm *tm)  static void set_time (m48t59_t *NVRAM, struct tm *tm)
 {  {
     NVRAM->alarm = mktime(tm);      NVRAM->time_offset = qemu_timedate_diff(tm);
     if (NVRAM->alrm_timer != NULL) {      set_alarm(NVRAM);
         qemu_del_timer(NVRAM->alrm_timer);  
         if (NVRAM->alarm - time(NULL) > 0)  
             qemu_mod_timer(NVRAM->alrm_timer, NVRAM->alarm * 1000);  
     }  
 }  }
   
 /* Watchdog management */  /* Watchdog management */
Line 229  void m48t59_write (void *opaque, uint32_ Line 203  void m48t59_write (void *opaque, uint32_
         /* alarm seconds */          /* alarm seconds */
         tmp = fromBCD(val & 0x7F);          tmp = fromBCD(val & 0x7F);
         if (tmp >= 0 && tmp <= 59) {          if (tmp >= 0 && tmp <= 59) {
             get_alarm(NVRAM, &tm);              NVRAM->alarm.tm_sec = tmp;
             tm.tm_sec = tmp;  
             NVRAM->buffer[0x1FF2] = val;              NVRAM->buffer[0x1FF2] = val;
             set_alarm(NVRAM, &tm);              set_alarm(NVRAM);
         }          }
         break;          break;
     case 0x1FF3:      case 0x1FF3:
         /* alarm minutes */          /* alarm minutes */
         tmp = fromBCD(val & 0x7F);          tmp = fromBCD(val & 0x7F);
         if (tmp >= 0 && tmp <= 59) {          if (tmp >= 0 && tmp <= 59) {
             get_alarm(NVRAM, &tm);              NVRAM->alarm.tm_min = tmp;
             tm.tm_min = tmp;  
             NVRAM->buffer[0x1FF3] = val;              NVRAM->buffer[0x1FF3] = val;
             set_alarm(NVRAM, &tm);              set_alarm(NVRAM);
         }          }
         break;          break;
     case 0x1FF4:      case 0x1FF4:
         /* alarm hours */          /* alarm hours */
         tmp = fromBCD(val & 0x3F);          tmp = fromBCD(val & 0x3F);
         if (tmp >= 0 && tmp <= 23) {          if (tmp >= 0 && tmp <= 23) {
             get_alarm(NVRAM, &tm);              NVRAM->alarm.tm_hour = tmp;
             tm.tm_hour = tmp;  
             NVRAM->buffer[0x1FF4] = val;              NVRAM->buffer[0x1FF4] = val;
             set_alarm(NVRAM, &tm);              set_alarm(NVRAM);
         }          }
         break;          break;
     case 0x1FF5:      case 0x1FF5:
         /* alarm date */          /* alarm date */
         tmp = fromBCD(val & 0x1F);          tmp = fromBCD(val & 0x1F);
         if (tmp != 0) {          if (tmp != 0) {
             get_alarm(NVRAM, &tm);              NVRAM->alarm.tm_mday = tmp;
             tm.tm_mday = tmp;  
             NVRAM->buffer[0x1FF5] = val;              NVRAM->buffer[0x1FF5] = val;
             set_alarm(NVRAM, &tm);              set_alarm(NVRAM);
         }          }
         break;          break;
     case 0x1FF6:      case 0x1FF6:
Line 288  void m48t59_write (void *opaque, uint32_ Line 258  void m48t59_write (void *opaque, uint32_
             tm.tm_sec = tmp;              tm.tm_sec = tmp;
             set_time(NVRAM, &tm);              set_time(NVRAM, &tm);
         }          }
        if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) {          if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) {
             if (val & 0x80) {              if (val & 0x80) {
                 NVRAM->stop_time = time(NULL);                  NVRAM->stop_time = time(NULL);
             } else {              } else {
Line 296  void m48t59_write (void *opaque, uint32_ Line 266  void m48t59_write (void *opaque, uint32_
                 NVRAM->stop_time = 0;                  NVRAM->stop_time = 0;
             }              }
         }          }
        NVRAM->buffer[addr] = val & 0x80;          NVRAM->buffer[addr] = val & 0x80;
         break;          break;
     case 0x1FFA:      case 0x1FFA:
     case 0x07FA:      case 0x07FA:
Line 543  static void nvram_writeb (void *opaque,  Line 513  static void nvram_writeb (void *opaque, 
 {  {
     m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
   
     addr -= NVRAM->mem_base;  
     m48t59_write(NVRAM, addr, value & 0xff);      m48t59_write(NVRAM, addr, value & 0xff);
 }  }
   
Line 551  static void nvram_writew (void *opaque,  Line 520  static void nvram_writew (void *opaque, 
 {  {
     m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
   
     addr -= NVRAM->mem_base;  
     m48t59_write(NVRAM, addr, (value >> 8) & 0xff);      m48t59_write(NVRAM, addr, (value >> 8) & 0xff);
     m48t59_write(NVRAM, addr + 1, value & 0xff);      m48t59_write(NVRAM, addr + 1, value & 0xff);
 }  }
Line 560  static void nvram_writel (void *opaque,  Line 528  static void nvram_writel (void *opaque, 
 {  {
     m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
   
     addr -= NVRAM->mem_base;  
     m48t59_write(NVRAM, addr, (value >> 24) & 0xff);      m48t59_write(NVRAM, addr, (value >> 24) & 0xff);
     m48t59_write(NVRAM, addr + 1, (value >> 16) & 0xff);      m48t59_write(NVRAM, addr + 1, (value >> 16) & 0xff);
     m48t59_write(NVRAM, addr + 2, (value >> 8) & 0xff);      m48t59_write(NVRAM, addr + 2, (value >> 8) & 0xff);
Line 572  static uint32_t nvram_readb (void *opaqu Line 539  static uint32_t nvram_readb (void *opaqu
     m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
     uint32_t retval;      uint32_t retval;
   
     addr -= NVRAM->mem_base;  
     retval = m48t59_read(NVRAM, addr);      retval = m48t59_read(NVRAM, addr);
     return retval;      return retval;
 }  }
Line 582  static uint32_t nvram_readw (void *opaqu Line 548  static uint32_t nvram_readw (void *opaqu
     m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
     uint32_t retval;      uint32_t retval;
   
     addr -= NVRAM->mem_base;  
     retval = m48t59_read(NVRAM, addr) << 8;      retval = m48t59_read(NVRAM, addr) << 8;
     retval |= m48t59_read(NVRAM, addr + 1);      retval |= m48t59_read(NVRAM, addr + 1);
     return retval;      return retval;
Line 593  static uint32_t nvram_readl (void *opaqu Line 558  static uint32_t nvram_readl (void *opaqu
     m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
     uint32_t retval;      uint32_t retval;
   
     addr -= NVRAM->mem_base;  
     retval = m48t59_read(NVRAM, addr) << 24;      retval = m48t59_read(NVRAM, addr) << 24;
     retval |= m48t59_read(NVRAM, addr + 1) << 16;      retval |= m48t59_read(NVRAM, addr + 1) << 16;
     retval |= m48t59_read(NVRAM, addr + 2) << 8;      retval |= m48t59_read(NVRAM, addr + 2) << 8;
Line 640  static void m48t59_reset(void *opaque) Line 604  static void m48t59_reset(void *opaque)
 {  {
     m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
   
       NVRAM->addr = 0;
       NVRAM->lock = 0;
     if (NVRAM->alrm_timer != NULL)      if (NVRAM->alrm_timer != NULL)
         qemu_del_timer(NVRAM->alrm_timer);          qemu_del_timer(NVRAM->alrm_timer);
   
Line 656  m48t59_t *m48t59_init (qemu_irq IRQ, tar Line 622  m48t59_t *m48t59_init (qemu_irq IRQ, tar
     target_phys_addr_t save_base;      target_phys_addr_t save_base;
   
     s = qemu_mallocz(sizeof(m48t59_t));      s = qemu_mallocz(sizeof(m48t59_t));
     if (!s)  
         return NULL;  
     s->buffer = qemu_mallocz(size);      s->buffer = qemu_mallocz(size);
     if (!s->buffer) {  
         qemu_free(s);  
         return NULL;  
     }  
     s->IRQ = IRQ;      s->IRQ = IRQ;
     s->size = size;      s->size = size;
     s->mem_base = mem_base;  
     s->io_base = io_base;      s->io_base = io_base;
     s->addr = 0;  
     s->type = type;      s->type = type;
     if (io_base != 0) {      if (io_base != 0) {
         register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s);          register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s);
Line 681  m48t59_t *m48t59_init (qemu_irq IRQ, tar Line 639  m48t59_t *m48t59_init (qemu_irq IRQ, tar
         s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s);          s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s);
         s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);          s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);
     }      }
     s->lock = 0;      qemu_get_timedate(&s->alarm, 0);
   
     qemu_register_reset(m48t59_reset, s);      qemu_register_reset(m48t59_reset, s);
     save_base = mem_base ? mem_base : io_base;      save_base = mem_base ? mem_base : io_base;

Removed from v.1.1.1.4  
changed lines
  Added in v.1.1.1.5


unix.superglobalmegacorp.com