49 |
49 |
* http://www.st.com/stonline/products/literature/od/7001/m48t59y.pdf
|
50 |
50 |
*/
|
51 |
51 |
|
52 |
|
struct m48t59_t {
|
|
52 |
struct M48t59State {
|
53 |
53 |
/* Model parameters */
|
54 |
54 |
uint32_t type; // 2 = m48t02, 8 = m48t08, 59 = m48t59
|
55 |
55 |
/* Hardware parameters */
|
... | ... | |
71 |
71 |
|
72 |
72 |
typedef struct M48t59ISAState {
|
73 |
73 |
ISADevice busdev;
|
74 |
|
m48t59_t state;
|
|
74 |
M48t59State state;
|
75 |
75 |
} M48t59ISAState;
|
76 |
76 |
|
77 |
77 |
typedef struct M48t59SysBusState {
|
78 |
78 |
SysBusDevice busdev;
|
79 |
|
m48t59_t state;
|
|
79 |
M48t59State state;
|
80 |
80 |
} M48t59SysBusState;
|
81 |
81 |
|
82 |
82 |
/* Fake timer functions */
|
... | ... | |
86 |
86 |
{
|
87 |
87 |
struct tm tm;
|
88 |
88 |
uint64_t next_time;
|
89 |
|
m48t59_t *NVRAM = opaque;
|
|
89 |
M48t59State *NVRAM = opaque;
|
90 |
90 |
|
91 |
91 |
qemu_set_irq(NVRAM->IRQ, 1);
|
92 |
92 |
if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 &&
|
... | ... | |
128 |
128 |
qemu_set_irq(NVRAM->IRQ, 0);
|
129 |
129 |
}
|
130 |
130 |
|
131 |
|
static void set_alarm (m48t59_t *NVRAM)
|
|
131 |
static void set_alarm(M48t59State *NVRAM)
|
132 |
132 |
{
|
133 |
133 |
int diff;
|
134 |
134 |
if (NVRAM->alrm_timer != NULL) {
|
... | ... | |
140 |
140 |
}
|
141 |
141 |
|
142 |
142 |
/* RTC management helpers */
|
143 |
|
static inline void get_time (m48t59_t *NVRAM, struct tm *tm)
|
|
143 |
static inline void get_time(M48t59State *NVRAM, struct tm *tm)
|
144 |
144 |
{
|
145 |
145 |
qemu_get_timedate(tm, NVRAM->time_offset);
|
146 |
146 |
}
|
147 |
147 |
|
148 |
|
static void set_time (m48t59_t *NVRAM, struct tm *tm)
|
|
148 |
static void set_time(M48t59State *NVRAM, struct tm *tm)
|
149 |
149 |
{
|
150 |
150 |
NVRAM->time_offset = qemu_timedate_diff(tm);
|
151 |
151 |
set_alarm(NVRAM);
|
... | ... | |
154 |
154 |
/* Watchdog management */
|
155 |
155 |
static void watchdog_cb (void *opaque)
|
156 |
156 |
{
|
157 |
|
m48t59_t *NVRAM = opaque;
|
|
157 |
M48t59State *NVRAM = opaque;
|
158 |
158 |
|
159 |
159 |
NVRAM->buffer[0x1FF0] |= 0x80;
|
160 |
160 |
if (NVRAM->buffer[0x1FF7] & 0x80) {
|
... | ... | |
168 |
168 |
}
|
169 |
169 |
}
|
170 |
170 |
|
171 |
|
static void set_up_watchdog (m48t59_t *NVRAM, uint8_t value)
|
|
171 |
static void set_up_watchdog(M48t59State *NVRAM, uint8_t value)
|
172 |
172 |
{
|
173 |
173 |
uint64_t interval; /* in 1/16 seconds */
|
174 |
174 |
|
... | ... | |
186 |
186 |
/* Direct access to NVRAM */
|
187 |
187 |
void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
|
188 |
188 |
{
|
189 |
|
m48t59_t *NVRAM = opaque;
|
|
189 |
M48t59State *NVRAM = opaque;
|
190 |
190 |
struct tm tm;
|
191 |
191 |
int tmp;
|
192 |
192 |
|
... | ... | |
354 |
354 |
|
355 |
355 |
uint32_t m48t59_read (void *opaque, uint32_t addr)
|
356 |
356 |
{
|
357 |
|
m48t59_t *NVRAM = opaque;
|
|
357 |
M48t59State *NVRAM = opaque;
|
358 |
358 |
struct tm tm;
|
359 |
359 |
uint32_t retval = 0xFF;
|
360 |
360 |
|
... | ... | |
461 |
461 |
|
462 |
462 |
void m48t59_set_addr (void *opaque, uint32_t addr)
|
463 |
463 |
{
|
464 |
|
m48t59_t *NVRAM = opaque;
|
|
464 |
M48t59State *NVRAM = opaque;
|
465 |
465 |
|
466 |
466 |
NVRAM->addr = addr;
|
467 |
467 |
}
|
468 |
468 |
|
469 |
469 |
void m48t59_toggle_lock (void *opaque, int lock)
|
470 |
470 |
{
|
471 |
|
m48t59_t *NVRAM = opaque;
|
|
471 |
M48t59State *NVRAM = opaque;
|
472 |
472 |
|
473 |
473 |
NVRAM->lock ^= 1 << lock;
|
474 |
474 |
}
|
... | ... | |
476 |
476 |
/* IO access to NVRAM */
|
477 |
477 |
static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val)
|
478 |
478 |
{
|
479 |
|
m48t59_t *NVRAM = opaque;
|
|
479 |
M48t59State *NVRAM = opaque;
|
480 |
480 |
|
481 |
481 |
addr -= NVRAM->io_base;
|
482 |
482 |
NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val);
|
... | ... | |
500 |
500 |
|
501 |
501 |
static uint32_t NVRAM_readb (void *opaque, uint32_t addr)
|
502 |
502 |
{
|
503 |
|
m48t59_t *NVRAM = opaque;
|
|
503 |
M48t59State *NVRAM = opaque;
|
504 |
504 |
uint32_t retval;
|
505 |
505 |
|
506 |
506 |
addr -= NVRAM->io_base;
|
... | ... | |
519 |
519 |
|
520 |
520 |
static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
|
521 |
521 |
{
|
522 |
|
m48t59_t *NVRAM = opaque;
|
|
522 |
M48t59State *NVRAM = opaque;
|
523 |
523 |
|
524 |
524 |
m48t59_write(NVRAM, addr, value & 0xff);
|
525 |
525 |
}
|
526 |
526 |
|
527 |
527 |
static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
|
528 |
528 |
{
|
529 |
|
m48t59_t *NVRAM = opaque;
|
|
529 |
M48t59State *NVRAM = opaque;
|
530 |
530 |
|
531 |
531 |
m48t59_write(NVRAM, addr, (value >> 8) & 0xff);
|
532 |
532 |
m48t59_write(NVRAM, addr + 1, value & 0xff);
|
... | ... | |
534 |
534 |
|
535 |
535 |
static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
|
536 |
536 |
{
|
537 |
|
m48t59_t *NVRAM = opaque;
|
|
537 |
M48t59State *NVRAM = opaque;
|
538 |
538 |
|
539 |
539 |
m48t59_write(NVRAM, addr, (value >> 24) & 0xff);
|
540 |
540 |
m48t59_write(NVRAM, addr + 1, (value >> 16) & 0xff);
|
... | ... | |
544 |
544 |
|
545 |
545 |
static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
|
546 |
546 |
{
|
547 |
|
m48t59_t *NVRAM = opaque;
|
|
547 |
M48t59State *NVRAM = opaque;
|
548 |
548 |
uint32_t retval;
|
549 |
549 |
|
550 |
550 |
retval = m48t59_read(NVRAM, addr);
|
... | ... | |
553 |
553 |
|
554 |
554 |
static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)
|
555 |
555 |
{
|
556 |
|
m48t59_t *NVRAM = opaque;
|
|
556 |
M48t59State *NVRAM = opaque;
|
557 |
557 |
uint32_t retval;
|
558 |
558 |
|
559 |
559 |
retval = m48t59_read(NVRAM, addr) << 8;
|
... | ... | |
563 |
563 |
|
564 |
564 |
static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)
|
565 |
565 |
{
|
566 |
|
m48t59_t *NVRAM = opaque;
|
|
566 |
M48t59State *NVRAM = opaque;
|
567 |
567 |
uint32_t retval;
|
568 |
568 |
|
569 |
569 |
retval = m48t59_read(NVRAM, addr) << 24;
|
... | ... | |
587 |
587 |
|
588 |
588 |
static void m48t59_save(QEMUFile *f, void *opaque)
|
589 |
589 |
{
|
590 |
|
m48t59_t *s = opaque;
|
|
590 |
M48t59State *s = opaque;
|
591 |
591 |
|
592 |
592 |
qemu_put_8s(f, &s->lock);
|
593 |
593 |
qemu_put_be16s(f, &s->addr);
|
... | ... | |
596 |
596 |
|
597 |
597 |
static int m48t59_load(QEMUFile *f, void *opaque, int version_id)
|
598 |
598 |
{
|
599 |
|
m48t59_t *s = opaque;
|
|
599 |
M48t59State *s = opaque;
|
600 |
600 |
|
601 |
601 |
if (version_id != 1)
|
602 |
602 |
return -EINVAL;
|
... | ... | |
608 |
608 |
return 0;
|
609 |
609 |
}
|
610 |
610 |
|
611 |
|
static void m48t59_reset_common(m48t59_t *NVRAM)
|
|
611 |
static void m48t59_reset_common(M48t59State *NVRAM)
|
612 |
612 |
{
|
613 |
613 |
NVRAM->addr = 0;
|
614 |
614 |
NVRAM->lock = 0;
|
... | ... | |
622 |
622 |
static void m48t59_reset_isa(DeviceState *d)
|
623 |
623 |
{
|
624 |
624 |
M48t59ISAState *isa = container_of(d, M48t59ISAState, busdev.qdev);
|
625 |
|
m48t59_t *NVRAM = &isa->state;
|
|
625 |
M48t59State *NVRAM = &isa->state;
|
626 |
626 |
|
627 |
627 |
m48t59_reset_common(NVRAM);
|
628 |
628 |
}
|
... | ... | |
630 |
630 |
static void m48t59_reset_sysbus(DeviceState *d)
|
631 |
631 |
{
|
632 |
632 |
M48t59SysBusState *sys = container_of(d, M48t59SysBusState, busdev.qdev);
|
633 |
|
m48t59_t *NVRAM = &sys->state;
|
|
633 |
M48t59State *NVRAM = &sys->state;
|
634 |
634 |
|
635 |
635 |
m48t59_reset_common(NVRAM);
|
636 |
636 |
}
|
637 |
637 |
|
638 |
638 |
/* Initialisation routine */
|
639 |
|
m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base,
|
640 |
|
uint32_t io_base, uint16_t size,
|
641 |
|
int type)
|
|
639 |
M48t59State *m48t59_init(qemu_irq IRQ, target_phys_addr_t mem_base,
|
|
640 |
uint32_t io_base, uint16_t size, int type)
|
642 |
641 |
{
|
643 |
642 |
DeviceState *dev;
|
644 |
643 |
SysBusDevice *s;
|
... | ... | |
664 |
663 |
return &d->state;
|
665 |
664 |
}
|
666 |
665 |
|
667 |
|
m48t59_t *m48t59_init_isa(uint32_t io_base, uint16_t size, int type)
|
|
666 |
M48t59State *m48t59_init_isa(uint32_t io_base, uint16_t size, int type)
|
668 |
667 |
{
|
669 |
668 |
M48t59ISAState *d;
|
670 |
669 |
ISADevice *dev;
|
671 |
|
m48t59_t *s;
|
|
670 |
M48t59State *s;
|
672 |
671 |
|
673 |
672 |
dev = isa_create("m48t59_isa");
|
674 |
673 |
qdev_prop_set_uint32(&dev->qdev, "type", type);
|
... | ... | |
686 |
685 |
return s;
|
687 |
686 |
}
|
688 |
687 |
|
689 |
|
static void m48t59_init_common(m48t59_t *s)
|
|
688 |
static void m48t59_init_common(M48t59State *s)
|
690 |
689 |
{
|
691 |
690 |
s->buffer = qemu_mallocz(s->size);
|
692 |
691 |
if (s->type == 59) {
|
... | ... | |
701 |
700 |
static int m48t59_init_isa1(ISADevice *dev)
|
702 |
701 |
{
|
703 |
702 |
M48t59ISAState *d = DO_UPCAST(M48t59ISAState, busdev, dev);
|
704 |
|
m48t59_t *s = &d->state;
|
|
703 |
M48t59State *s = &d->state;
|
705 |
704 |
|
706 |
705 |
isa_init_irq(dev, &s->IRQ, 8);
|
707 |
706 |
m48t59_init_common(s);
|
... | ... | |
712 |
711 |
static int m48t59_init1(SysBusDevice *dev)
|
713 |
712 |
{
|
714 |
713 |
M48t59SysBusState *d = FROM_SYSBUS(M48t59SysBusState, dev);
|
715 |
|
m48t59_t *s = &d->state;
|
|
714 |
M48t59State *s = &d->state;
|
716 |
715 |
int mem_index;
|
717 |
716 |
|
718 |
717 |
sysbus_init_irq(dev, &s->IRQ);
|