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

Diff of /qemu/hw/m48t08.c

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

revision 1.2 by bellard, Mon Oct 4 21:23:09 2004 UTC revision 1.3 by bellard, Sun Dec 19 23:18:01 2004 UTC
# 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  #define NVRAM_MAX_MEM 0xfff0  #define NVRAM_MAX_MEM 0x1ff0
36    #define NVRAM_MAXADDR 0x1fff
37    
38  struct m48t08_t {  struct m48t08_t {
     /* Hardware parameters */  
     int mem_index;  
     uint32_t mem_base;  
     uint16_t size;  
39      /* RTC management */      /* RTC management */
40      time_t   time_offset;      time_t   time_offset;
41      time_t   stop_time;      time_t   stop_time;
42      /* NVRAM storage */      /* NVRAM storage */
     uint8_t  lock;  
     uint16_t addr;  
43      uint8_t *buffer;      uint8_t *buffer;
44  };  };
45    
# Line 83  static void set_time (m48t08_t *NVRAM, s Line 78  static void set_time (m48t08_t *NVRAM, s
78  }  }
79    
80  /* Direct access to NVRAM */  /* Direct access to NVRAM */
81  void m48t08_write (m48t08_t *NVRAM, uint32_t val)  void m48t08_write (m48t08_t *NVRAM, uint32_t addr, uint8_t val)
82  {  {
83      struct tm tm;      struct tm tm;
84      int tmp;      int tmp;
85    
86      if (NVRAM->addr > NVRAM_MAX_MEM && NVRAM->addr < 0x2000)      addr &= NVRAM_MAXADDR;
87          NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, NVRAM->addr, val);      switch (addr) {
     switch (NVRAM->addr) {  
88      case 0x1FF8:      case 0x1FF8:
89          /* control */          /* control */
90          NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90;          NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90;
# Line 167  void m48t08_write (m48t08_t *NVRAM, uint Line 161  void m48t08_write (m48t08_t *NVRAM, uint
161          }          }
162          break;          break;
163      default:      default:
164          /* Check lock registers state */          NVRAM->buffer[addr] = val & 0xFF;
         if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))  
             break;  
         if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))  
             break;  
         if (NVRAM->addr < NVRAM_MAX_MEM ||  
             (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {  
             NVRAM->buffer[NVRAM->addr] = val & 0xFF;  
         }  
165          break;          break;
166      }      }
167  }  }
168    
169  uint32_t m48t08_read (m48t08_t *NVRAM)  uint8_t m48t08_read (m48t08_t *NVRAM, uint32_t addr)
170  {  {
171      struct tm tm;      struct tm tm;
172      uint32_t retval = 0xFF;      uint8_t retval = 0xFF;
173    
174      switch (NVRAM->addr) {      addr &= NVRAM_MAXADDR;
175        switch (addr) {
176      case 0x1FF8:      case 0x1FF8:
177          /* control */          /* control */
178          goto do_read;          goto do_read;
# Line 225  uint32_t m48t08_read (m48t08_t *NVRAM) Line 212  uint32_t m48t08_read (m48t08_t *NVRAM)
212          retval = toBCD(tm.tm_year);          retval = toBCD(tm.tm_year);
213          break;          break;
214      default:      default:
215          /* Check lock registers state */      do_read:
216          if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))          retval = NVRAM->buffer[addr];
             break;  
         if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))  
             break;  
         if (NVRAM->addr < NVRAM_MAX_MEM ||  
             (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {  
         do_read:  
             retval = NVRAM->buffer[NVRAM->addr];  
         }  
217          break;          break;
218      }      }
     if (NVRAM->addr > NVRAM_MAX_MEM + 1 && NVRAM->addr < 0x2000)  
         NVRAM_PRINTF("0x%08x <= 0x%08x\n", NVRAM->addr, retval);  
   
219      return retval;      return retval;
220  }  }
221    
 void m48t08_set_addr (m48t08_t *NVRAM, uint32_t addr)  
 {  
     NVRAM->addr = addr;  
 }  
   
 void m48t08_toggle_lock (m48t08_t *NVRAM, int lock)  
 {  
     NVRAM->lock ^= 1 << lock;  
 }  
   
222  static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)  static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
223  {  {
224      m48t08_t *NVRAM = opaque;      m48t08_t *NVRAM = opaque;
225            
226      addr -= NVRAM->mem_base;      m48t08_write(NVRAM, addr, value);
     if (addr < NVRAM_MAX_MEM)  
         NVRAM->buffer[addr] = value;  
227  }  }
228    
229  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)
230  {  {
231      m48t08_t *NVRAM = opaque;      m48t08_t *NVRAM = opaque;
232            
233      addr -= NVRAM->mem_base;      m48t08_write(NVRAM, addr, value);
234      if (addr < NVRAM_MAX_MEM) {      m48t08_write(NVRAM, addr + 1, value >> 8);
         NVRAM->buffer[addr] = value >> 8;  
         NVRAM->buffer[addr + 1] = value;  
     }  
235  }  }
236    
237  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)
238  {  {
239      m48t08_t *NVRAM = opaque;      m48t08_t *NVRAM = opaque;
240            
241      addr -= NVRAM->mem_base;      m48t08_write(NVRAM, addr, value);
242      if (addr < NVRAM_MAX_MEM) {      m48t08_write(NVRAM, addr + 1, value >> 8);
243          NVRAM->buffer[addr] = value >> 24;      m48t08_write(NVRAM, addr + 2, value >> 16);
244          NVRAM->buffer[addr + 1] = value >> 16;      m48t08_write(NVRAM, addr + 3, value >> 24);
         NVRAM->buffer[addr + 2] = value >> 8;  
         NVRAM->buffer[addr + 3] = value;  
     }  
245  }  }
246    
247  static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)  static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
# Line 291  static uint32_t nvram_readb (void *opaqu Line 249  static uint32_t nvram_readb (void *opaqu
249      m48t08_t *NVRAM = opaque;      m48t08_t *NVRAM = opaque;
250      uint32_t retval = 0;      uint32_t retval = 0;
251            
252      addr -= NVRAM->mem_base;      retval = m48t08_read(NVRAM, addr);
     if (addr < NVRAM_MAX_MEM)  
         retval = NVRAM->buffer[addr];  
   
253      return retval;      return retval;
254  }  }
255    
# Line 303  static uint32_t nvram_readw (void *opaqu Line 258  static uint32_t nvram_readw (void *opaqu
258      m48t08_t *NVRAM = opaque;      m48t08_t *NVRAM = opaque;
259      uint32_t retval = 0;      uint32_t retval = 0;
260            
261      addr -= NVRAM->mem_base;      retval = m48t08_read(NVRAM, addr) << 8;
262      if (addr < NVRAM_MAX_MEM) {      retval |= m48t08_read(NVRAM, addr + 1);
         retval = NVRAM->buffer[addr] << 8;  
         retval |= NVRAM->buffer[addr + 1];  
     }  
   
263      return retval;      return retval;
264  }  }
265    
# Line 317  static uint32_t nvram_readl (void *opaqu Line 268  static uint32_t nvram_readl (void *opaqu
268      m48t08_t *NVRAM = opaque;      m48t08_t *NVRAM = opaque;
269      uint32_t retval = 0;      uint32_t retval = 0;
270            
271      addr -= NVRAM->mem_base;      retval = m48t08_read(NVRAM, addr) << 24;
272      if (addr < NVRAM_MAX_MEM) {      retval |= m48t08_read(NVRAM, addr + 1) << 16;
273          retval = NVRAM->buffer[addr] << 24;      retval |= m48t08_read(NVRAM, addr + 2) << 8;
274          retval |= NVRAM->buffer[addr + 1] << 16;      retval |= m48t08_read(NVRAM, addr + 3);
         retval |= NVRAM->buffer[addr + 2] << 8;  
         retval |= NVRAM->buffer[addr + 3];  
     }  
   
275      return retval;      return retval;
276  }  }
277    
# Line 340  static CPUReadMemoryFunc *nvram_read[] = Line 287  static CPUReadMemoryFunc *nvram_read[] =
287      &nvram_readl,      &nvram_readl,
288  };  };
289    
290    static void nvram_save(QEMUFile *f, void *opaque)
291    {
292        m48t08_t *s = opaque;
293        
294        qemu_put_be32s(f, (uint32_t *)&s->time_offset);
295        qemu_put_be32s(f, (uint32_t *)&s->stop_time);
296        qemu_put_buffer(f, s->buffer, 0x2000);
297    }
298    
299    static int nvram_load(QEMUFile *f, void *opaque, int version_id)
300    {
301        m48t08_t *s = opaque;
302        
303        if (version_id != 1)
304            return -EINVAL;
305    
306        qemu_get_be32s(f, (uint32_t *)&s->time_offset);
307        qemu_get_be32s(f, (uint32_t *)&s->stop_time);
308        qemu_get_buffer(f, s->buffer, 0x2000);
309        return 0;
310    }
311    
312    static void m48t08_reset(void *opaque)
313    {
314        m48t08_t *s = opaque;
315    
316        s->time_offset = 0;
317        s->stop_time = 0;
318    }
319    
320    
321  /* Initialisation routine */  /* Initialisation routine */
322  m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr)  m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size)
323  {  {
324      m48t08_t *s;      m48t08_t *s;
325      int i;      int mem_index;
     unsigned char tmp = 0;  
326    
327      s = qemu_mallocz(sizeof(m48t08_t));      s = qemu_mallocz(sizeof(m48t08_t));
328      if (!s)      if (!s)
# Line 355  m48t08_t *m48t08_init(uint32_t mem_base, Line 332  m48t08_t *m48t08_init(uint32_t mem_base,
332          qemu_free(s);          qemu_free(s);
333          return NULL;          return NULL;
334      }      }
     s->size = size;  
     s->mem_base = mem_base;  
     s->addr = 0;  
335      if (mem_base != 0) {      if (mem_base != 0) {
336          s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);          mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
337          cpu_register_physical_memory(mem_base, 0x4000, s->mem_index);          cpu_register_physical_memory(mem_base, 0x2000, mem_index);
338      }      }
     s->lock = 0;  
339    
340      i = 0x1fd8;      register_savevm("nvram", mem_base, 1, nvram_save, nvram_load, s);
341      s->buffer[i++] = 0x01;      qemu_register_reset(m48t08_reset, s);
     s->buffer[i++] = 0x80; /* Sun4m OBP */  
     memcpy(&s->buffer[i], macaddr, 6);  
   
     /* Calculate checksum */  
     for (i = 0x1fd8; i < 0x1fe7; i++) {  
         tmp ^= s->buffer[i];  
     }  
     s->buffer[0x1fe7] = tmp;  
342      return s;      return s;
343  }  }
344    

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

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