/[qemu]/qemu/hw/m48t59.c
ViewVC logotype

Diff of /qemu/hw/m48t59.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.6 by bellard, Mon Jun 21 16:49:53 2004 UTC revision 1.7 by bellard, Sun Oct 30 16:58:32 2005 UTC
# Line 1  Line 1 
1  /*  /*
2   * QEMU M48T59 NVRAM emulation for PPC PREP platform   * QEMU M48T59 and M48T08 NVRAM emulation for PPC PREP and Sparc platforms
3   *   *
4   * Copyright (c) 2003-2004 Jocelyn Mayer   * Copyright (c) 2003-2005 Jocelyn Mayer
5   *   *
6   * Permission is hereby granted, free of charge, to any person obtaining a copy   * 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   * of this software and associated documentation files (the "Software"), to deal
# Line 32  Line 32 
32  #define NVRAM_PRINTF(fmt, args...) do { } while (0)  #define NVRAM_PRINTF(fmt, args...) do { } while (0)
33  #endif  #endif
34    
35    /*
36     * The M48T08 and M48T59 chips are very similar. The newer '59 has
37     * alarm and a watchdog timer and related control registers. In the
38     * PPC platform there is also a nvram lock function.
39     */
40  struct m48t59_t {  struct m48t59_t {
41        /* Model parameters */
42        int type; // 8 = m48t08, 59 = m48t59
43      /* Hardware parameters */      /* Hardware parameters */
44      int      IRQ;      int      IRQ;
45      int mem_index;      int mem_index;
# Line 188  static void set_up_watchdog (m48t59_t *N Line 195  static void set_up_watchdog (m48t59_t *N
195  }  }
196    
197  /* Direct access to NVRAM */  /* Direct access to NVRAM */
198  void m48t59_write (m48t59_t *NVRAM, uint32_t val)  void m48t59_write (m48t59_t *NVRAM, uint32_t addr, uint32_t val)
199  {  {
200      struct tm tm;      struct tm tm;
201      int tmp;      int tmp;
202    
203      if (NVRAM->addr > 0x1FF8 && NVRAM->addr < 0x2000)      if (addr > 0x1FF8 && addr < 0x2000)
204          NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, NVRAM->addr, val);          NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val);
205      switch (NVRAM->addr) {      if (NVRAM->type == 8 &&
206            (addr >= 0x1ff0 && addr <= 0x1ff7))
207            goto do_write;
208        switch (addr) {
209      case 0x1FF0:      case 0x1FF0:
210          /* flags register : read-only */          /* flags register : read-only */
211          break;          break;
# Line 204  void m48t59_write (m48t59_t *NVRAM, uint Line 214  void m48t59_write (m48t59_t *NVRAM, uint
214          break;          break;
215      case 0x1FF2:      case 0x1FF2:
216          /* alarm seconds */          /* alarm seconds */
217          tmp = fromBCD(val & 0x7F);          tmp = fromBCD(val & 0x7F);
218          if (tmp >= 0 && tmp <= 59) {          if (tmp >= 0 && tmp <= 59) {
219              get_alarm(NVRAM, &tm);              get_alarm(NVRAM, &tm);
220              tm.tm_sec = tmp;              tm.tm_sec = tmp;
221              NVRAM->buffer[0x1FF2] = val;              NVRAM->buffer[0x1FF2] = val;
222              set_alarm(NVRAM, &tm);              set_alarm(NVRAM, &tm);
223          }          }
224          break;          break;
225      case 0x1FF3:      case 0x1FF3:
226          /* alarm minutes */          /* alarm minutes */
227          tmp = fromBCD(val & 0x7F);          tmp = fromBCD(val & 0x7F);
228          if (tmp >= 0 && tmp <= 59) {          if (tmp >= 0 && tmp <= 59) {
229              get_alarm(NVRAM, &tm);              get_alarm(NVRAM, &tm);
230              tm.tm_min = tmp;              tm.tm_min = tmp;
231              NVRAM->buffer[0x1FF3] = val;              NVRAM->buffer[0x1FF3] = val;
232              set_alarm(NVRAM, &tm);              set_alarm(NVRAM, &tm);
233          }          }
234          break;          break;
235      case 0x1FF4:      case 0x1FF4:
236          /* alarm hours */          /* alarm hours */
237          tmp = fromBCD(val & 0x3F);          tmp = fromBCD(val & 0x3F);
238          if (tmp >= 0 && tmp <= 23) {          if (tmp >= 0 && tmp <= 23) {
239              get_alarm(NVRAM, &tm);              get_alarm(NVRAM, &tm);
240              tm.tm_hour = tmp;              tm.tm_hour = tmp;
241              NVRAM->buffer[0x1FF4] = val;              NVRAM->buffer[0x1FF4] = val;
242              set_alarm(NVRAM, &tm);              set_alarm(NVRAM, &tm);
243          }          }
244          break;          break;
245      case 0x1FF5:      case 0x1FF5:
246          /* alarm date */          /* alarm date */
247          tmp = fromBCD(val & 0x1F);          tmp = fromBCD(val & 0x1F);
248          if (tmp != 0) {          if (tmp != 0) {
249              get_alarm(NVRAM, &tm);              get_alarm(NVRAM, &tm);
250              tm.tm_mday = tmp;              tm.tm_mday = tmp;
251              NVRAM->buffer[0x1FF5] = val;              NVRAM->buffer[0x1FF5] = val;
252              set_alarm(NVRAM, &tm);              set_alarm(NVRAM, &tm);
253          }          }
254          break;          break;
255      case 0x1FF6:      case 0x1FF6:
256          /* interrupts */          /* interrupts */
257          NVRAM->buffer[0x1FF6] = val;          NVRAM->buffer[0x1FF6] = val;
258          break;          break;
259      case 0x1FF7:      case 0x1FF7:
260          /* watchdog */          /* watchdog */
261          NVRAM->buffer[0x1FF7] = val;          NVRAM->buffer[0x1FF7] = val;
262          set_up_watchdog(NVRAM, val);          set_up_watchdog(NVRAM, val);
263          break;          break;
264      case 0x1FF8:      case 0x1FF8:
265          /* control */          /* control */
# Line 328  void m48t59_write (m48t59_t *NVRAM, uint Line 338  void m48t59_write (m48t59_t *NVRAM, uint
338          break;          break;
339      default:      default:
340          /* Check lock registers state */          /* Check lock registers state */
341          if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))          if (addr >= 0x20 && addr <= 0x2F && (NVRAM->lock & 1))
342              break;              break;
343          if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))          if (addr >= 0x30 && addr <= 0x3F && (NVRAM->lock & 2))
344              break;              break;
345          if (NVRAM->addr < 0x1FF0 ||      do_write:
346              (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {          if (addr < NVRAM->size) {
347              NVRAM->buffer[NVRAM->addr] = val & 0xFF;              NVRAM->buffer[addr] = val & 0xFF;
348          }          }
349          break;          break;
350      }      }
351  }  }
352    
353  uint32_t m48t59_read (m48t59_t *NVRAM)  uint32_t m48t59_read (m48t59_t *NVRAM, uint32_t addr)
354  {  {
355      struct tm tm;      struct tm tm;
356      uint32_t retval = 0xFF;      uint32_t retval = 0xFF;
357    
358      switch (NVRAM->addr) {      if (NVRAM->type == 8 &&
359            (addr >= 0x1ff0 && addr <= 0x1ff7))
360            goto do_read;
361        switch (addr) {
362      case 0x1FF0:      case 0x1FF0:
363          /* flags register */          /* flags register */
364          goto do_read;          goto do_read;
# Line 412  uint32_t m48t59_read (m48t59_t *NVRAM) Line 425  uint32_t m48t59_read (m48t59_t *NVRAM)
425          break;          break;
426      default:      default:
427          /* Check lock registers state */          /* Check lock registers state */
428          if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))          if (addr >= 0x20 && addr <= 0x2F && (NVRAM->lock & 1))
429              break;              break;
430          if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))          if (addr >= 0x30 && addr <= 0x3F && (NVRAM->lock & 2))
431              break;              break;
432          if (NVRAM->addr < 0x1FF0 ||      do_read:
433              (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {          if (addr < NVRAM->size) {
434          do_read:              retval = NVRAM->buffer[addr];
             retval = NVRAM->buffer[NVRAM->addr];  
435          }          }
436          break;          break;
437      }      }
438      if (NVRAM->addr > 0x1FF9 && NVRAM->addr < 0x2000)      if (addr > 0x1FF9 && addr < 0x2000)
439          NVRAM_PRINTF("0x%08x <= 0x%08x\n", NVRAM->addr, retval);          NVRAM_PRINTF("0x%08x <= 0x%08x\n", addr, retval);
440    
441      return retval;      return retval;
442  }  }
# Line 456  static void NVRAM_writeb (void *opaque, Line 468  static void NVRAM_writeb (void *opaque,
468          NVRAM->addr |= val << 8;          NVRAM->addr |= val << 8;
469          break;          break;
470      case 3:      case 3:
471          m48t59_write(NVRAM, val);          m48t59_write(NVRAM, val, NVRAM->addr);
472          NVRAM->addr = 0x0000;          NVRAM->addr = 0x0000;
473          break;          break;
474      default:      default:
# Line 472  static uint32_t NVRAM_readb (void *opaqu Line 484  static uint32_t NVRAM_readb (void *opaqu
484      addr -= NVRAM->io_base;      addr -= NVRAM->io_base;
485      switch (addr) {      switch (addr) {
486      case 3:      case 3:
487          retval = m48t59_read(NVRAM);          retval = m48t59_read(NVRAM, NVRAM->addr);
488          break;          break;
489      default:      default:
490          retval = -1;          retval = -1;
# Line 488  static void nvram_writeb (void *opaque, Line 500  static void nvram_writeb (void *opaque,
500      m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
501            
502      addr -= NVRAM->mem_base;      addr -= NVRAM->mem_base;
503      if (addr < 0x1FF0)      m48t59_write(NVRAM, addr, value & 0xff);
         NVRAM->buffer[addr] = value;  
504  }  }
505    
506  static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value)  static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
# Line 497  static void nvram_writew (void *opaque, Line 508  static void nvram_writew (void *opaque,
508      m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
509            
510      addr -= NVRAM->mem_base;      addr -= NVRAM->mem_base;
511      if (addr < 0x1FF0) {      m48t59_write(NVRAM, addr, (value >> 8) & 0xff);
512          NVRAM->buffer[addr] = value >> 8;      m48t59_write(NVRAM, addr + 1, value & 0xff);
         NVRAM->buffer[addr + 1] = value;  
     }  
513  }  }
514    
515  static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value)  static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
# Line 508  static void nvram_writel (void *opaque, Line 517  static void nvram_writel (void *opaque,
517      m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
518            
519      addr -= NVRAM->mem_base;      addr -= NVRAM->mem_base;
520      if (addr < 0x1FF0) {      m48t59_write(NVRAM, addr, (value >> 24) & 0xff);
521          NVRAM->buffer[addr] = value >> 24;      m48t59_write(NVRAM, addr + 1, (value >> 16) & 0xff);
522          NVRAM->buffer[addr + 1] = value >> 16;      m48t59_write(NVRAM, addr + 2, (value >> 8) & 0xff);
523          NVRAM->buffer[addr + 2] = value >> 8;      m48t59_write(NVRAM, addr + 3, value & 0xff);
         NVRAM->buffer[addr + 3] = value;  
     }  
524  }  }
525    
526  static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)  static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
527  {  {
528      m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
529      uint32_t retval = 0;      uint32_t retval;
530            
531      addr -= NVRAM->mem_base;      addr -= NVRAM->mem_base;
532      if (addr < 0x1FF0)      retval = m48t59_read(NVRAM, addr);
         retval = NVRAM->buffer[addr];  
   
533      return retval;      return retval;
534  }  }
535    
536  static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)  static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)
537  {  {
538      m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
539      uint32_t retval = 0;      uint32_t retval;
540            
541      addr -= NVRAM->mem_base;      addr -= NVRAM->mem_base;
542      if (addr < 0x1FF0) {      retval = m48t59_read(NVRAM, addr) << 8;
543          retval = NVRAM->buffer[addr] << 8;      retval |= m48t59_read(NVRAM, addr + 1);
         retval |= NVRAM->buffer[addr + 1];  
     }  
   
544      return retval;      return retval;
545  }  }
546    
547  static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)  static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)
548  {  {
549      m48t59_t *NVRAM = opaque;      m48t59_t *NVRAM = opaque;
550      uint32_t retval = 0;      uint32_t retval;
       
     addr -= NVRAM->mem_base;  
     if (addr < 0x1FF0) {  
         retval = NVRAM->buffer[addr] << 24;  
         retval |= NVRAM->buffer[addr + 1] << 16;  
         retval |= NVRAM->buffer[addr + 2] << 8;  
         retval |= NVRAM->buffer[addr + 3];  
     }  
551    
552        addr -= NVRAM->mem_base;
553        retval = m48t59_read(NVRAM, addr) << 24;
554        retval |= m48t59_read(NVRAM, addr + 1) << 16;
555        retval |= m48t59_read(NVRAM, addr + 2) << 8;
556        retval |= m48t59_read(NVRAM, addr + 3);
557      return retval;      return retval;
558  }  }
559    
# Line 569  static CPUReadMemoryFunc *nvram_read[] = Line 568  static CPUReadMemoryFunc *nvram_read[] =
568      &nvram_readw,      &nvram_readw,
569      &nvram_readl,      &nvram_readl,
570  };  };
571    
572  /* Initialisation routine */  /* Initialisation routine */
573  m48t59_t *m48t59_init (int IRQ, uint32_t mem_base,  m48t59_t *m48t59_init (int IRQ, target_ulong mem_base,
574                         uint32_t io_base, uint16_t size)                         uint32_t io_base, uint16_t size,
575                           int type)
576  {  {
577      m48t59_t *s;      m48t59_t *s;
578    
# Line 588  m48t59_t *m48t59_init (int IRQ, uint32_t Line 589  m48t59_t *m48t59_init (int IRQ, uint32_t
589      s->mem_base = mem_base;      s->mem_base = mem_base;
590      s->io_base = io_base;      s->io_base = io_base;
591      s->addr = 0;      s->addr = 0;
592      register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s);      s->type = type;
593      register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s);      if (io_base != 0) {
594            register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s);
595            register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s);
596        }
597      if (mem_base != 0) {      if (mem_base != 0) {
598          s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);          s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
599          cpu_register_physical_memory(mem_base, 0x4000, s->mem_index);          cpu_register_physical_memory(mem_base, 0x4000, s->mem_index);
600      }      }
601      s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s);      if (type == 59) {
602      s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);          s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s);
603            s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);
604        }
605      s->lock = 0;      s->lock = 0;
606    
607      return s;      return s;

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26