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"
38
#if defined(DEBUG_NVRAM)
39
#define NVRAM_PRINTF(fmt, ...) do { printf(fmt , ## __VA_ARGS__); } while (0)
41
#define NVRAM_PRINTF(fmt, ...) do { } while (0)
35
#include "m48t59-internal.h"
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)
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)
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.
66
typedef struct M48txxInfo {
68
const char *sysbus_name;
69
uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
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
80
typedef struct M48t59State {
81
/* Hardware parameters */
89
/* Alarm & watchdog */
91
QEMUTimer *alrm_timer;
95
/* Model parameters */
96
uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
102
typedef struct M48txxISAState {
103
ISADevice parent_obj;
109
typedef struct M48txxISADeviceClass {
110
ISADeviceClass parent_class;
112
} M48txxISADeviceClass;
114
52
typedef struct M48txxSysBusState {
115
53
SysBusDevice parent_obj;
116
54
M48t59State state;
123
61
} M48txxSysBusDeviceClass;
125
static M48txxInfo m48txx_info[] = {
63
static M48txxInfo m48txx_sysbus_info[] = {
127
.sysbus_name = "sysbus-m48t02",
65
.bus_name = "sysbus-m48t02",
131
.sysbus_name = "sysbus-m48t08",
69
.bus_name = "sysbus-m48t08",
135
.sysbus_name = "sysbus-m48t59",
139
.isa_name = "isa-m48t59",
73
.bus_name = "sysbus-m48t59",
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)
520
static void m48t59_toggle_lock(M48t59State *NVRAM, int lock)
522
NVRAM->lock ^= 1 << lock;
525
454
/* IO access to NVRAM */
526
455
static void NVRAM_writeb(void *opaque, hwaddr addr, uint64_t val,
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()
642
static void m48t59_reset_common(M48t59State *NVRAM)
571
void m48t59_reset_common(M48t59State *NVRAM)
650
579
timer_del(NVRAM->wd_timer);
653
static void m48t59_reset_isa(DeviceState *d)
655
M48txxISAState *isa = M48TXX_ISA(d);
656
M48t59State *NVRAM = &isa->state;
658
m48t59_reset_common(NVRAM);
661
582
static void m48t59_reset_sysbus(DeviceState *d)
663
584
M48txxSysBusState *sys = M48TXX_SYS_BUS(d);
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) {
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);
715
Nvram *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
716
int base_year, int model)
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) {
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);
739
static void m48t59_realize_common(M48t59State *s, Error **errp)
635
void m48t59_realize_common(M48t59State *s, Error **errp)
741
637
s->buffer = g_malloc0(s->size);
742
638
if (s->model == 59) {
748
644
vmstate_register(NULL, -1, &vmstate_m48t59, s);
751
static void m48t59_isa_realize(DeviceState *dev, Error **errp)
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;
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);
768
647
static int m48t59_init1(SysBusDevice *dev)
770
649
M48txxSysBusDeviceClass *u = M48TXX_SYS_BUS_GET_CLASS(dev);
794
static uint32_t m48txx_isa_read(Nvram *obj, uint32_t addr)
796
M48txxISAState *d = M48TXX_ISA(obj);
797
return m48t59_read(&d->state, addr);
800
static void m48txx_isa_write(Nvram *obj, uint32_t addr, uint32_t val)
802
M48txxISAState *d = M48TXX_ISA(obj);
803
m48t59_write(&d->state, addr, val);
806
static void m48txx_isa_toggle_lock(Nvram *obj, int lock)
808
M48txxISAState *d = M48TXX_ISA(obj);
809
m48t59_toggle_lock(&d->state, lock);
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(),
818
static void m48txx_isa_class_init(ObjectClass *klass, void *data)
820
DeviceClass *dc = DEVICE_CLASS(klass);
821
NvramClass *nc = NVRAM_CLASS(klass);
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;
831
static void m48txx_isa_concrete_class_init(ObjectClass *klass, void *data)
833
M48txxISADeviceClass *u = M48TXX_ISA_CLASS(klass);
834
M48txxInfo *info = data;
839
673
static uint32_t m48txx_sysbus_read(Nvram *obj, uint32_t addr)
841
675
M48txxSysBusState *d = M48TXX_SYS_BUS(obj);
902
static const TypeInfo m48txx_isa_type_info = {
903
.name = TYPE_M48TXX_ISA,
904
.parent = TYPE_ISA_DEVICE,
905
.instance_size = sizeof(M48txxISAState),
907
.class_init = m48txx_isa_class_init,
908
.interfaces = (InterfaceInfo[]) {
914
736
static void m48t59_register_types(void)
916
738
TypeInfo sysbus_type_info = {
918
740
.class_size = sizeof(M48txxSysBusDeviceClass),
919
741
.class_init = m48txx_sysbus_concrete_class_init,
921
TypeInfo isa_type_info = {
922
.parent = TYPE_M48TXX_ISA,
923
.class_size = sizeof(M48txxISADeviceClass),
924
.class_init = m48txx_isa_concrete_class_init,
928
745
type_register_static(&nvram_info);
929
746
type_register_static(&m48txx_sysbus_type_info);
930
type_register_static(&m48txx_isa_type_info);
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);
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);
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);