~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to hw/timer/m48t59.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include "qemu/timer.h"
30
30
#include "sysemu/sysemu.h"
31
31
#include "hw/sysbus.h"
32
 
#include "hw/isa/isa.h"
33
32
#include "exec/address-spaces.h"
34
33
#include "qemu/bcd.h"
35
34
 
36
 
//#define DEBUG_NVRAM
37
 
 
38
 
#if defined(DEBUG_NVRAM)
39
 
#define NVRAM_PRINTF(fmt, ...) do { printf(fmt , ## __VA_ARGS__); } while (0)
40
 
#else
41
 
#define NVRAM_PRINTF(fmt, ...) do { } while (0)
42
 
#endif
 
35
#include "m48t59-internal.h"
43
36
 
44
37
#define TYPE_M48TXX_SYS_BUS "sysbus-m48txx"
45
38
#define M48TXX_SYS_BUS_GET_CLASS(obj) \
49
42
#define M48TXX_SYS_BUS(obj) \
50
43
    OBJECT_CHECK(M48txxSysBusState, (obj), TYPE_M48TXX_SYS_BUS)
51
44
 
52
 
#define TYPE_M48TXX_ISA "isa-m48txx"
53
 
#define M48TXX_ISA_GET_CLASS(obj) \
54
 
    OBJECT_GET_CLASS(M48txxISADeviceClass, (obj), TYPE_M48TXX_ISA)
55
 
#define M48TXX_ISA_CLASS(klass) \
56
 
    OBJECT_CLASS_CHECK(M48txxISADeviceClass, (klass), TYPE_M48TXX_ISA)
57
 
#define M48TXX_ISA(obj) \
58
 
    OBJECT_CHECK(M48txxISAState, (obj), TYPE_M48TXX_ISA)
59
 
 
60
 
/*
61
 
 * The M48T02, M48T08 and M48T59 chips are very similar. The newer '59 has
62
 
 * alarm and a watchdog timer and related control registers. In the
63
 
 * PPC platform there is also a nvram lock function.
64
 
 */
65
 
 
66
 
typedef struct M48txxInfo {
67
 
    const char *isa_name;
68
 
    const char *sysbus_name;
69
 
    uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
70
 
    uint32_t size;
71
 
} M48txxInfo;
72
 
 
73
45
/*
74
46
 * Chipset docs:
75
47
 * http://www.st.com/stonline/products/literature/ds/2410/m48t02.pdf
77
49
 * http://www.st.com/stonline/products/literature/od/7001/m48t59y.pdf
78
50
 */
79
51
 
80
 
typedef struct M48t59State {
81
 
    /* Hardware parameters */
82
 
    qemu_irq IRQ;
83
 
    MemoryRegion iomem;
84
 
    uint32_t size;
85
 
    int32_t base_year;
86
 
    /* RTC management */
87
 
    time_t   time_offset;
88
 
    time_t   stop_time;
89
 
    /* Alarm & watchdog */
90
 
    struct tm alarm;
91
 
    QEMUTimer *alrm_timer;
92
 
    QEMUTimer *wd_timer;
93
 
    /* NVRAM storage */
94
 
    uint8_t *buffer;
95
 
    /* Model parameters */
96
 
    uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
97
 
    /* NVRAM storage */
98
 
    uint16_t addr;
99
 
    uint8_t  lock;
100
 
} M48t59State;
101
 
 
102
 
typedef struct M48txxISAState {
103
 
    ISADevice parent_obj;
104
 
    M48t59State state;
105
 
    uint32_t io_base;
106
 
    MemoryRegion io;
107
 
} M48txxISAState;
108
 
 
109
 
typedef struct M48txxISADeviceClass {
110
 
    ISADeviceClass parent_class;
111
 
    M48txxInfo info;
112
 
} M48txxISADeviceClass;
113
 
 
114
52
typedef struct M48txxSysBusState {
115
53
    SysBusDevice parent_obj;
116
54
    M48t59State state;
122
60
    M48txxInfo info;
123
61
} M48txxSysBusDeviceClass;
124
62
 
125
 
static M48txxInfo m48txx_info[] = {
 
63
static M48txxInfo m48txx_sysbus_info[] = {
126
64
    {
127
 
        .sysbus_name = "sysbus-m48t02",
 
65
        .bus_name = "sysbus-m48t02",
128
66
        .model = 2,
129
67
        .size = 0x800,
130
68
    },{
131
 
        .sysbus_name = "sysbus-m48t08",
 
69
        .bus_name = "sysbus-m48t08",
132
70
        .model = 8,
133
71
        .size = 0x2000,
134
72
    },{
135
 
        .sysbus_name = "sysbus-m48t59",
136
 
        .model = 59,
137
 
        .size = 0x2000,
138
 
    },{
139
 
        .isa_name = "isa-m48t59",
 
73
        .bus_name = "sysbus-m48t59",
140
74
        .model = 59,
141
75
        .size = 0x2000,
142
76
    }
248
182
}
249
183
 
250
184
/* Direct access to NVRAM */
251
 
static void m48t59_write(M48t59State *NVRAM, uint32_t addr, uint32_t val)
 
185
void m48t59_write(M48t59State *NVRAM, uint32_t addr, uint32_t val)
252
186
{
253
187
    struct tm tm;
254
188
    int tmp;
413
347
    }
414
348
}
415
349
 
416
 
static uint32_t m48t59_read(M48t59State *NVRAM, uint32_t addr)
 
350
uint32_t m48t59_read(M48t59State *NVRAM, uint32_t addr)
417
351
{
418
352
    struct tm tm;
419
353
    uint32_t retval = 0xFF;
517
451
    return retval;
518
452
}
519
453
 
520
 
static void m48t59_toggle_lock(M48t59State *NVRAM, int lock)
521
 
{
522
 
    NVRAM->lock ^= 1 << lock;
523
 
}
524
 
 
525
454
/* IO access to NVRAM */
526
455
static void NVRAM_writeb(void *opaque, hwaddr addr, uint64_t val,
527
456
                         unsigned size)
634
563
    .fields = (VMStateField[]) {
635
564
        VMSTATE_UINT8(lock, M48t59State),
636
565
        VMSTATE_UINT16(addr, M48t59State),
637
 
        VMSTATE_VBUFFER_UINT32(buffer, M48t59State, 0, NULL, 0, size),
 
566
        VMSTATE_VBUFFER_UINT32(buffer, M48t59State, 0, NULL, size),
638
567
        VMSTATE_END_OF_LIST()
639
568
    }
640
569
};
641
570
 
642
 
static void m48t59_reset_common(M48t59State *NVRAM)
 
571
void m48t59_reset_common(M48t59State *NVRAM)
643
572
{
644
573
    NVRAM->addr = 0;
645
574
    NVRAM->lock = 0;
650
579
        timer_del(NVRAM->wd_timer);
651
580
}
652
581
 
653
 
static void m48t59_reset_isa(DeviceState *d)
654
 
{
655
 
    M48txxISAState *isa = M48TXX_ISA(d);
656
 
    M48t59State *NVRAM = &isa->state;
657
 
 
658
 
    m48t59_reset_common(NVRAM);
659
 
}
660
 
 
661
582
static void m48t59_reset_sysbus(DeviceState *d)
662
583
{
663
584
    M48txxSysBusState *sys = M48TXX_SYS_BUS(d);
666
587
    m48t59_reset_common(NVRAM);
667
588
}
668
589
 
669
 
static const MemoryRegionOps m48t59_io_ops = {
 
590
const MemoryRegionOps m48t59_io_ops = {
670
591
    .read = NVRAM_readb,
671
592
    .write = NVRAM_writeb,
672
593
    .impl = {
685
606
    SysBusDevice *s;
686
607
    int i;
687
608
 
688
 
    for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
689
 
        if (!m48txx_info[i].sysbus_name ||
690
 
            m48txx_info[i].size != size ||
691
 
            m48txx_info[i].model != model) {
 
609
    for (i = 0; i < ARRAY_SIZE(m48txx_sysbus_info); i++) {
 
610
        if (m48txx_sysbus_info[i].size != size ||
 
611
            m48txx_sysbus_info[i].model != model) {
692
612
            continue;
693
613
        }
694
614
 
695
 
        dev = qdev_create(NULL, m48txx_info[i].sysbus_name);
 
615
        dev = qdev_create(NULL, m48txx_sysbus_info[i].bus_name);
696
616
        qdev_prop_set_int32(dev, "base-year", base_year);
697
617
        qdev_init_nofail(dev);
698
618
        s = SYS_BUS_DEVICE(dev);
712
632
    return NULL;
713
633
}
714
634
 
715
 
Nvram *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
716
 
                       int base_year, int model)
717
 
{
718
 
    DeviceState *dev;
719
 
    int i;
720
 
 
721
 
    for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
722
 
        if (!m48txx_info[i].isa_name ||
723
 
            m48txx_info[i].size != size ||
724
 
            m48txx_info[i].model != model) {
725
 
            continue;
726
 
        }
727
 
 
728
 
        dev = DEVICE(isa_create(bus, m48txx_info[i].isa_name));
729
 
        qdev_prop_set_uint32(dev, "iobase", io_base);
730
 
        qdev_prop_set_int32(dev, "base-year", base_year);
731
 
        qdev_init_nofail(dev);
732
 
        return NVRAM(dev);
733
 
    }
734
 
 
735
 
    assert(false);
736
 
    return NULL;
737
 
}
738
 
 
739
 
static void m48t59_realize_common(M48t59State *s, Error **errp)
 
635
void m48t59_realize_common(M48t59State *s, Error **errp)
740
636
{
741
637
    s->buffer = g_malloc0(s->size);
742
638
    if (s->model == 59) {
748
644
    vmstate_register(NULL, -1, &vmstate_m48t59, s);
749
645
}
750
646
 
751
 
static void m48t59_isa_realize(DeviceState *dev, Error **errp)
752
 
{
753
 
    M48txxISADeviceClass *u = M48TXX_ISA_GET_CLASS(dev);
754
 
    ISADevice *isadev = ISA_DEVICE(dev);
755
 
    M48txxISAState *d = M48TXX_ISA(dev);
756
 
    M48t59State *s = &d->state;
757
 
 
758
 
    s->model = u->info.model;
759
 
    s->size = u->info.size;
760
 
    isa_init_irq(isadev, &s->IRQ, 8);
761
 
    m48t59_realize_common(s, errp);
762
 
    memory_region_init_io(&d->io, OBJECT(dev), &m48t59_io_ops, s, "m48t59", 4);
763
 
    if (d->io_base != 0) {
764
 
        isa_register_ioport(isadev, &d->io, d->io_base);
765
 
    }
766
 
}
767
 
 
768
647
static int m48t59_init1(SysBusDevice *dev)
769
648
{
770
649
    M48txxSysBusDeviceClass *u = M48TXX_SYS_BUS_GET_CLASS(dev);
791
670
    return 0;
792
671
}
793
672
 
794
 
static uint32_t m48txx_isa_read(Nvram *obj, uint32_t addr)
795
 
{
796
 
    M48txxISAState *d = M48TXX_ISA(obj);
797
 
    return m48t59_read(&d->state, addr);
798
 
}
799
 
 
800
 
static void m48txx_isa_write(Nvram *obj, uint32_t addr, uint32_t val)
801
 
{
802
 
    M48txxISAState *d = M48TXX_ISA(obj);
803
 
    m48t59_write(&d->state, addr, val);
804
 
}
805
 
 
806
 
static void m48txx_isa_toggle_lock(Nvram *obj, int lock)
807
 
{
808
 
    M48txxISAState *d = M48TXX_ISA(obj);
809
 
    m48t59_toggle_lock(&d->state, lock);
810
 
}
811
 
 
812
 
static Property m48t59_isa_properties[] = {
813
 
    DEFINE_PROP_INT32("base-year", M48txxISAState, state.base_year, 0),
814
 
    DEFINE_PROP_UINT32("iobase", M48txxISAState, io_base, 0x74),
815
 
    DEFINE_PROP_END_OF_LIST(),
816
 
};
817
 
 
818
 
static void m48txx_isa_class_init(ObjectClass *klass, void *data)
819
 
{
820
 
    DeviceClass *dc = DEVICE_CLASS(klass);
821
 
    NvramClass *nc = NVRAM_CLASS(klass);
822
 
 
823
 
    dc->realize = m48t59_isa_realize;
824
 
    dc->reset = m48t59_reset_isa;
825
 
    dc->props = m48t59_isa_properties;
826
 
    nc->read = m48txx_isa_read;
827
 
    nc->write = m48txx_isa_write;
828
 
    nc->toggle_lock = m48txx_isa_toggle_lock;
829
 
}
830
 
 
831
 
static void m48txx_isa_concrete_class_init(ObjectClass *klass, void *data)
832
 
{
833
 
    M48txxISADeviceClass *u = M48TXX_ISA_CLASS(klass);
834
 
    M48txxInfo *info = data;
835
 
 
836
 
    u->info = *info;
837
 
}
838
 
 
839
673
static uint32_t m48txx_sysbus_read(Nvram *obj, uint32_t addr)
840
674
{
841
675
    M48txxSysBusState *d = M48TXX_SYS_BUS(obj);
899
733
    }
900
734
};
901
735
 
902
 
static const TypeInfo m48txx_isa_type_info = {
903
 
    .name = TYPE_M48TXX_ISA,
904
 
    .parent = TYPE_ISA_DEVICE,
905
 
    .instance_size = sizeof(M48txxISAState),
906
 
    .abstract = true,
907
 
    .class_init = m48txx_isa_class_init,
908
 
    .interfaces = (InterfaceInfo[]) {
909
 
        { TYPE_NVRAM },
910
 
        { }
911
 
    }
912
 
};
913
 
 
914
736
static void m48t59_register_types(void)
915
737
{
916
738
    TypeInfo sysbus_type_info = {
918
740
        .class_size = sizeof(M48txxSysBusDeviceClass),
919
741
        .class_init = m48txx_sysbus_concrete_class_init,
920
742
    };
921
 
    TypeInfo isa_type_info = {
922
 
        .parent = TYPE_M48TXX_ISA,
923
 
        .class_size = sizeof(M48txxISADeviceClass),
924
 
        .class_init = m48txx_isa_concrete_class_init,
925
 
    };
926
743
    int i;
927
744
 
928
745
    type_register_static(&nvram_info);
929
746
    type_register_static(&m48txx_sysbus_type_info);
930
 
    type_register_static(&m48txx_isa_type_info);
931
 
 
932
 
    for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
933
 
        if (m48txx_info[i].sysbus_name) {
934
 
            sysbus_type_info.name = m48txx_info[i].sysbus_name;
935
 
            sysbus_type_info.class_data = &m48txx_info[i];
936
 
            type_register(&sysbus_type_info);
937
 
        }
938
 
 
939
 
        if (m48txx_info[i].isa_name) {
940
 
            isa_type_info.name = m48txx_info[i].isa_name;
941
 
            isa_type_info.class_data = &m48txx_info[i];
942
 
            type_register(&isa_type_info);
943
 
        }
 
747
 
 
748
    for (i = 0; i < ARRAY_SIZE(m48txx_sysbus_info); i++) {
 
749
        sysbus_type_info.name = m48txx_sysbus_info[i].bus_name;
 
750
        sysbus_type_info.class_data = &m48txx_sysbus_info[i];
 
751
        type_register(&sysbus_type_info);
944
752
    }
945
753
}
946
754