hw: Move M48T59 device from hw/timer/ to hw/rtc/ subdirectory
authorPhilippe Mathieu-Daudé <philmd@redhat.com>
Thu, 3 Oct 2019 23:03:54 +0000 (01:03 +0200)
committerLaurent Vivier <laurent@vivier.eu>
Thu, 24 Oct 2019 18:20:45 +0000 (20:20 +0200)
The M48T59 is a Real Time Clock, not a timer.
Move it under the hw/rtc/ subdirectory.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20191003230404.19384-5-philmd@redhat.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
17 files changed:
MAINTAINERS
hw/ppc/ppc405_boards.c
hw/ppc/prep.c
hw/rtc/Kconfig
hw/rtc/Makefile.objs
hw/rtc/m48t59-internal.h [new file with mode: 0644]
hw/rtc/m48t59-isa.c [new file with mode: 0644]
hw/rtc/m48t59.c [new file with mode: 0644]
hw/sparc/sun4m.c
hw/sparc64/sun4u.c
hw/timer/Kconfig
hw/timer/Makefile.objs
hw/timer/m48t59-internal.h [deleted file]
hw/timer/m48t59-isa.c [deleted file]
hw/timer/m48t59.c [deleted file]
include/hw/rtc/m48t59.h [new file with mode: 0644]
include/hw/timer/m48t59.h [deleted file]

index 7eba146444ae3df27524e7d474a9f9076a9e740a..4e65f062f29c75797bfd1be44c124105acede8fa 100644 (file)
@@ -1064,9 +1064,9 @@ F: hw/pci-host/prep.[hc]
 F: hw/isa/i82378.c
 F: hw/isa/pc87312.c
 F: hw/dma/i82374.c
-F: hw/timer/m48t59-isa.c
+F: hw/rtc/m48t59-isa.c
 F: include/hw/isa/pc87312.h
-F: include/hw/timer/m48t59.h
+F: include/hw/rtc/m48t59.h
 F: pc-bios/ppc_rom.bin
 
 sPAPR
index 388cae0b43709d7a8f506ef22bca8b8201dc0c9a..1f721feed6a4bfc128187aefb5d9afa9c549c056 100644 (file)
@@ -29,7 +29,7 @@
 #include "cpu.h"
 #include "hw/ppc/ppc.h"
 #include "ppc405.h"
-#include "hw/timer/m48t59.h"
+#include "hw/rtc/m48t59.h"
 #include "hw/block/flash.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/qtest.h"
index 3a51536e1a39ae939bd5365fb20280ccd94c7bd0..862345c2ac5f5a26d90602f8d5ef21231cbc0ec7 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "hw/timer/m48t59.h"
+#include "hw/rtc/m48t59.h"
 #include "hw/char/serial.h"
 #include "hw/block/fdc.h"
 #include "net/net.h"
index 7ffd702268ad2627e1361008e54f84a875e5bdff..159c2335171a0ed94b6fdc7640b1c665b4b8e44a 100644 (file)
@@ -1,3 +1,6 @@
+config M48T59
+    bool
+
 config PL031
     bool
 
index 3cac0d5a637b3d30dbba0e55277136908b70ff21..c87f81405e9ddf72ebc7152a08ab2dab1b7b8339 100644 (file)
@@ -1,2 +1,6 @@
+common-obj-$(CONFIG_M48T59) += m48t59.o
+ifeq ($(CONFIG_ISA_BUS),y)
+common-obj-$(CONFIG_M48T59) += m48t59-isa.o
+endif
 common-obj-$(CONFIG_PL031) += pl031.o
 obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
diff --git a/hw/rtc/m48t59-internal.h b/hw/rtc/m48t59-internal.h
new file mode 100644 (file)
index 0000000..4d4f2a6
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * QEMU M48T59 and M48T08 NVRAM emulation (common header)
+ *
+ * Copyright (c) 2003-2005, 2007 Jocelyn Mayer
+ * Copyright (c) 2013 Hervé Poussineau
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_M48T59_INTERNAL_H
+#define HW_M48T59_INTERNAL_H
+
+#define M48T59_DEBUG 0
+
+#define NVRAM_PRINTF(fmt, ...) do { \
+    if (M48T59_DEBUG) { printf(fmt , ## __VA_ARGS__); } } while (0)
+
+/*
+ * The M48T02, M48T08 and M48T59 chips are very similar. The newer '59 has
+ * alarm and a watchdog timer and related control registers. In the
+ * PPC platform there is also a nvram lock function.
+ */
+
+typedef struct M48txxInfo {
+    const char *bus_name;
+    uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
+    uint32_t size;
+} M48txxInfo;
+
+typedef struct M48t59State {
+    /* Hardware parameters */
+    qemu_irq IRQ;
+    MemoryRegion iomem;
+    uint32_t size;
+    int32_t base_year;
+    /* RTC management */
+    time_t   time_offset;
+    time_t   stop_time;
+    /* Alarm & watchdog */
+    struct tm alarm;
+    QEMUTimer *alrm_timer;
+    QEMUTimer *wd_timer;
+    /* NVRAM storage */
+    uint8_t *buffer;
+    /* Model parameters */
+    uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
+    /* NVRAM storage */
+    uint16_t addr;
+    uint8_t  lock;
+} M48t59State;
+
+uint32_t m48t59_read(M48t59State *NVRAM, uint32_t addr);
+void m48t59_write(M48t59State *NVRAM, uint32_t addr, uint32_t val);
+void m48t59_reset_common(M48t59State *NVRAM);
+void m48t59_realize_common(M48t59State *s, Error **errp);
+
+static inline void m48t59_toggle_lock(M48t59State *NVRAM, int lock)
+{
+    NVRAM->lock ^= 1 << lock;
+}
+
+extern const MemoryRegionOps m48t59_io_ops;
+
+#endif /* HW_M48T59_INTERNAL_H */
diff --git a/hw/rtc/m48t59-isa.c b/hw/rtc/m48t59-isa.c
new file mode 100644 (file)
index 0000000..7fde854
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * QEMU M48T59 and M48T08 NVRAM emulation (ISA bus interface)
+ *
+ * Copyright (c) 2003-2005, 2007 Jocelyn Mayer
+ * Copyright (c) 2013 Hervé Poussineau
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/isa/isa.h"
+#include "hw/qdev-properties.h"
+#include "hw/rtc/m48t59.h"
+#include "m48t59-internal.h"
+#include "qemu/module.h"
+
+#define TYPE_M48TXX_ISA "isa-m48txx"
+#define M48TXX_ISA_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(M48txxISADeviceClass, (obj), TYPE_M48TXX_ISA)
+#define M48TXX_ISA_CLASS(klass) \
+    OBJECT_CLASS_CHECK(M48txxISADeviceClass, (klass), TYPE_M48TXX_ISA)
+#define M48TXX_ISA(obj) \
+    OBJECT_CHECK(M48txxISAState, (obj), TYPE_M48TXX_ISA)
+
+typedef struct M48txxISAState {
+    ISADevice parent_obj;
+    M48t59State state;
+    uint32_t io_base;
+    MemoryRegion io;
+} M48txxISAState;
+
+typedef struct M48txxISADeviceClass {
+    ISADeviceClass parent_class;
+    M48txxInfo info;
+} M48txxISADeviceClass;
+
+static M48txxInfo m48txx_isa_info[] = {
+    {
+        .bus_name = "isa-m48t59",
+        .model = 59,
+        .size = 0x2000,
+    }
+};
+
+Nvram *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
+                       int base_year, int model)
+{
+    DeviceState *dev;
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(m48txx_isa_info); i++) {
+        if (m48txx_isa_info[i].size != size ||
+            m48txx_isa_info[i].model != model) {
+            continue;
+        }
+
+        dev = DEVICE(isa_create(bus, m48txx_isa_info[i].bus_name));
+        qdev_prop_set_uint32(dev, "iobase", io_base);
+        qdev_prop_set_int32(dev, "base-year", base_year);
+        qdev_init_nofail(dev);
+        return NVRAM(dev);
+    }
+
+    assert(false);
+    return NULL;
+}
+
+static uint32_t m48txx_isa_read(Nvram *obj, uint32_t addr)
+{
+    M48txxISAState *d = M48TXX_ISA(obj);
+    return m48t59_read(&d->state, addr);
+}
+
+static void m48txx_isa_write(Nvram *obj, uint32_t addr, uint32_t val)
+{
+    M48txxISAState *d = M48TXX_ISA(obj);
+    m48t59_write(&d->state, addr, val);
+}
+
+static void m48txx_isa_toggle_lock(Nvram *obj, int lock)
+{
+    M48txxISAState *d = M48TXX_ISA(obj);
+    m48t59_toggle_lock(&d->state, lock);
+}
+
+static Property m48t59_isa_properties[] = {
+    DEFINE_PROP_INT32("base-year", M48txxISAState, state.base_year, 0),
+    DEFINE_PROP_UINT32("iobase", M48txxISAState, io_base, 0x74),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void m48t59_reset_isa(DeviceState *d)
+{
+    M48txxISAState *isa = M48TXX_ISA(d);
+    M48t59State *NVRAM = &isa->state;
+
+    m48t59_reset_common(NVRAM);
+}
+
+static void m48t59_isa_realize(DeviceState *dev, Error **errp)
+{
+    M48txxISADeviceClass *u = M48TXX_ISA_GET_CLASS(dev);
+    ISADevice *isadev = ISA_DEVICE(dev);
+    M48txxISAState *d = M48TXX_ISA(dev);
+    M48t59State *s = &d->state;
+
+    s->model = u->info.model;
+    s->size = u->info.size;
+    isa_init_irq(isadev, &s->IRQ, 8);
+    m48t59_realize_common(s, errp);
+    memory_region_init_io(&d->io, OBJECT(dev), &m48t59_io_ops, s, "m48t59", 4);
+    if (d->io_base != 0) {
+        isa_register_ioport(isadev, &d->io, d->io_base);
+    }
+}
+
+static void m48txx_isa_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    NvramClass *nc = NVRAM_CLASS(klass);
+
+    dc->realize = m48t59_isa_realize;
+    dc->reset = m48t59_reset_isa;
+    dc->props = m48t59_isa_properties;
+    nc->read = m48txx_isa_read;
+    nc->write = m48txx_isa_write;
+    nc->toggle_lock = m48txx_isa_toggle_lock;
+}
+
+static void m48txx_isa_concrete_class_init(ObjectClass *klass, void *data)
+{
+    M48txxISADeviceClass *u = M48TXX_ISA_CLASS(klass);
+    M48txxInfo *info = data;
+
+    u->info = *info;
+}
+
+static const TypeInfo m48txx_isa_type_info = {
+    .name = TYPE_M48TXX_ISA,
+    .parent = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(M48txxISAState),
+    .abstract = true,
+    .class_init = m48txx_isa_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_NVRAM },
+        { }
+    }
+};
+
+static void m48t59_isa_register_types(void)
+{
+    TypeInfo isa_type_info = {
+        .parent = TYPE_M48TXX_ISA,
+        .class_size = sizeof(M48txxISADeviceClass),
+        .class_init = m48txx_isa_concrete_class_init,
+    };
+    int i;
+
+    type_register_static(&m48txx_isa_type_info);
+
+    for (i = 0; i < ARRAY_SIZE(m48txx_isa_info); i++) {
+        isa_type_info.name = m48txx_isa_info[i].bus_name;
+        isa_type_info.class_data = &m48txx_isa_info[i];
+        type_register(&isa_type_info);
+    }
+}
+
+type_init(m48t59_isa_register_types)
diff --git a/hw/rtc/m48t59.c b/hw/rtc/m48t59.c
new file mode 100644 (file)
index 0000000..fc592b9
--- /dev/null
@@ -0,0 +1,723 @@
+/*
+ * QEMU M48T59 and M48T08 NVRAM emulation for PPC PREP and Sparc platforms
+ *
+ * Copyright (c) 2003-2005, 2007, 2017 Jocelyn Mayer
+ * Copyright (c) 2013 Hervé Poussineau
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/rtc/m48t59.h"
+#include "qemu/timer.h"
+#include "sysemu/runstate.h"
+#include "sysemu/sysemu.h"
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "qemu/bcd.h"
+#include "qemu/module.h"
+
+#include "m48t59-internal.h"
+#include "migration/vmstate.h"
+
+#define TYPE_M48TXX_SYS_BUS "sysbus-m48txx"
+#define M48TXX_SYS_BUS_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(M48txxSysBusDeviceClass, (obj), TYPE_M48TXX_SYS_BUS)
+#define M48TXX_SYS_BUS_CLASS(klass) \
+    OBJECT_CLASS_CHECK(M48txxSysBusDeviceClass, (klass), TYPE_M48TXX_SYS_BUS)
+#define M48TXX_SYS_BUS(obj) \
+    OBJECT_CHECK(M48txxSysBusState, (obj), TYPE_M48TXX_SYS_BUS)
+
+/*
+ * Chipset docs:
+ * http://www.st.com/stonline/products/literature/ds/2410/m48t02.pdf
+ * http://www.st.com/stonline/products/literature/ds/2411/m48t08.pdf
+ * http://www.st.com/stonline/products/literature/od/7001/m48t59y.pdf
+ */
+
+typedef struct M48txxSysBusState {
+    SysBusDevice parent_obj;
+    M48t59State state;
+    MemoryRegion io;
+} M48txxSysBusState;
+
+typedef struct M48txxSysBusDeviceClass {
+    SysBusDeviceClass parent_class;
+    M48txxInfo info;
+} M48txxSysBusDeviceClass;
+
+static M48txxInfo m48txx_sysbus_info[] = {
+    {
+        .bus_name = "sysbus-m48t02",
+        .model = 2,
+        .size = 0x800,
+    },{
+        .bus_name = "sysbus-m48t08",
+        .model = 8,
+        .size = 0x2000,
+    },{
+        .bus_name = "sysbus-m48t59",
+        .model = 59,
+        .size = 0x2000,
+    }
+};
+
+
+/* Fake timer functions */
+
+/* Alarm management */
+static void alarm_cb (void *opaque)
+{
+    struct tm tm;
+    uint64_t next_time;
+    M48t59State *NVRAM = opaque;
+
+    qemu_set_irq(NVRAM->IRQ, 1);
+    if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 &&
+       (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
+       (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
+       (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
+        /* Repeat once a month */
+        qemu_get_timedate(&tm, NVRAM->time_offset);
+        tm.tm_mon++;
+        if (tm.tm_mon == 13) {
+            tm.tm_mon = 1;
+            tm.tm_year++;
+        }
+        next_time = qemu_timedate_diff(&tm) - NVRAM->time_offset;
+    } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
+              (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
+              (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
+              (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
+        /* Repeat once a day */
+        next_time = 24 * 60 * 60;
+    } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
+              (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
+              (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
+              (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
+        /* Repeat once an hour */
+        next_time = 60 * 60;
+    } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
+              (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
+              (NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
+              (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
+        /* Repeat once a minute */
+        next_time = 60;
+    } else {
+        /* Repeat once a second */
+        next_time = 1;
+    }
+    timer_mod(NVRAM->alrm_timer, qemu_clock_get_ns(rtc_clock) +
+                    next_time * 1000);
+    qemu_set_irq(NVRAM->IRQ, 0);
+}
+
+static void set_alarm(M48t59State *NVRAM)
+{
+    int diff;
+    if (NVRAM->alrm_timer != NULL) {
+        timer_del(NVRAM->alrm_timer);
+        diff = qemu_timedate_diff(&NVRAM->alarm) - NVRAM->time_offset;
+        if (diff > 0)
+            timer_mod(NVRAM->alrm_timer, diff * 1000);
+    }
+}
+
+/* RTC management helpers */
+static inline void get_time(M48t59State *NVRAM, struct tm *tm)
+{
+    qemu_get_timedate(tm, NVRAM->time_offset);
+}
+
+static void set_time(M48t59State *NVRAM, struct tm *tm)
+{
+    NVRAM->time_offset = qemu_timedate_diff(tm);
+    set_alarm(NVRAM);
+}
+
+/* Watchdog management */
+static void watchdog_cb (void *opaque)
+{
+    M48t59State *NVRAM = opaque;
+
+    NVRAM->buffer[0x1FF0] |= 0x80;
+    if (NVRAM->buffer[0x1FF7] & 0x80) {
+       NVRAM->buffer[0x1FF7] = 0x00;
+       NVRAM->buffer[0x1FFC] &= ~0x40;
+        /* May it be a hw CPU Reset instead ? */
+        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+    } else {
+       qemu_set_irq(NVRAM->IRQ, 1);
+       qemu_set_irq(NVRAM->IRQ, 0);
+    }
+}
+
+static void set_up_watchdog(M48t59State *NVRAM, uint8_t value)
+{
+    uint64_t interval; /* in 1/16 seconds */
+
+    NVRAM->buffer[0x1FF0] &= ~0x80;
+    if (NVRAM->wd_timer != NULL) {
+        timer_del(NVRAM->wd_timer);
+        if (value != 0) {
+            interval = (1 << (2 * (value & 0x03))) * ((value >> 2) & 0x1F);
+            timer_mod(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
+                           ((interval * 1000) >> 4));
+        }
+    }
+}
+
+/* Direct access to NVRAM */
+void m48t59_write(M48t59State *NVRAM, uint32_t addr, uint32_t val)
+{
+    struct tm tm;
+    int tmp;
+
+    if (addr > 0x1FF8 && addr < 0x2000)
+       NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val);
+
+    /* check for NVRAM access */
+    if ((NVRAM->model == 2 && addr < 0x7f8) ||
+        (NVRAM->model == 8 && addr < 0x1ff8) ||
+        (NVRAM->model == 59 && addr < 0x1ff0)) {
+        goto do_write;
+    }
+
+    /* TOD access */
+    switch (addr) {
+    case 0x1FF0:
+        /* flags register : read-only */
+        break;
+    case 0x1FF1:
+        /* unused */
+        break;
+    case 0x1FF2:
+        /* alarm seconds */
+        tmp = from_bcd(val & 0x7F);
+        if (tmp >= 0 && tmp <= 59) {
+            NVRAM->alarm.tm_sec = tmp;
+            NVRAM->buffer[0x1FF2] = val;
+            set_alarm(NVRAM);
+        }
+        break;
+    case 0x1FF3:
+        /* alarm minutes */
+        tmp = from_bcd(val & 0x7F);
+        if (tmp >= 0 && tmp <= 59) {
+            NVRAM->alarm.tm_min = tmp;
+            NVRAM->buffer[0x1FF3] = val;
+            set_alarm(NVRAM);
+        }
+        break;
+    case 0x1FF4:
+        /* alarm hours */
+        tmp = from_bcd(val & 0x3F);
+        if (tmp >= 0 && tmp <= 23) {
+            NVRAM->alarm.tm_hour = tmp;
+            NVRAM->buffer[0x1FF4] = val;
+            set_alarm(NVRAM);
+        }
+        break;
+    case 0x1FF5:
+        /* alarm date */
+        tmp = from_bcd(val & 0x3F);
+        if (tmp != 0) {
+            NVRAM->alarm.tm_mday = tmp;
+            NVRAM->buffer[0x1FF5] = val;
+            set_alarm(NVRAM);
+        }
+        break;
+    case 0x1FF6:
+        /* interrupts */
+        NVRAM->buffer[0x1FF6] = val;
+        break;
+    case 0x1FF7:
+        /* watchdog */
+        NVRAM->buffer[0x1FF7] = val;
+        set_up_watchdog(NVRAM, val);
+        break;
+    case 0x1FF8:
+    case 0x07F8:
+        /* control */
+       NVRAM->buffer[addr] = (val & ~0xA0) | 0x90;
+        break;
+    case 0x1FF9:
+    case 0x07F9:
+        /* seconds (BCD) */
+       tmp = from_bcd(val & 0x7F);
+       if (tmp >= 0 && tmp <= 59) {
+           get_time(NVRAM, &tm);
+           tm.tm_sec = tmp;
+           set_time(NVRAM, &tm);
+       }
+        if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) {
+           if (val & 0x80) {
+               NVRAM->stop_time = time(NULL);
+           } else {
+               NVRAM->time_offset += NVRAM->stop_time - time(NULL);
+               NVRAM->stop_time = 0;
+           }
+       }
+        NVRAM->buffer[addr] = val & 0x80;
+        break;
+    case 0x1FFA:
+    case 0x07FA:
+        /* minutes (BCD) */
+       tmp = from_bcd(val & 0x7F);
+       if (tmp >= 0 && tmp <= 59) {
+           get_time(NVRAM, &tm);
+           tm.tm_min = tmp;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    case 0x1FFB:
+    case 0x07FB:
+        /* hours (BCD) */
+       tmp = from_bcd(val & 0x3F);
+       if (tmp >= 0 && tmp <= 23) {
+           get_time(NVRAM, &tm);
+           tm.tm_hour = tmp;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    case 0x1FFC:
+    case 0x07FC:
+        /* day of the week / century */
+       tmp = from_bcd(val & 0x07);
+       get_time(NVRAM, &tm);
+       tm.tm_wday = tmp;
+       set_time(NVRAM, &tm);
+        NVRAM->buffer[addr] = val & 0x40;
+        break;
+    case 0x1FFD:
+    case 0x07FD:
+        /* date (BCD) */
+       tmp = from_bcd(val & 0x3F);
+       if (tmp != 0) {
+           get_time(NVRAM, &tm);
+           tm.tm_mday = tmp;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    case 0x1FFE:
+    case 0x07FE:
+        /* month */
+       tmp = from_bcd(val & 0x1F);
+       if (tmp >= 1 && tmp <= 12) {
+           get_time(NVRAM, &tm);
+           tm.tm_mon = tmp - 1;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    case 0x1FFF:
+    case 0x07FF:
+        /* year */
+       tmp = from_bcd(val);
+       if (tmp >= 0 && tmp <= 99) {
+           get_time(NVRAM, &tm);
+            tm.tm_year = from_bcd(val) + NVRAM->base_year - 1900;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    default:
+        /* Check lock registers state */
+        if (addr >= 0x20 && addr <= 0x2F && (NVRAM->lock & 1))
+            break;
+        if (addr >= 0x30 && addr <= 0x3F && (NVRAM->lock & 2))
+            break;
+    do_write:
+        if (addr < NVRAM->size) {
+            NVRAM->buffer[addr] = val & 0xFF;
+       }
+        break;
+    }
+}
+
+uint32_t m48t59_read(M48t59State *NVRAM, uint32_t addr)
+{
+    struct tm tm;
+    uint32_t retval = 0xFF;
+
+    /* check for NVRAM access */
+    if ((NVRAM->model == 2 && addr < 0x078f) ||
+        (NVRAM->model == 8 && addr < 0x1ff8) ||
+        (NVRAM->model == 59 && addr < 0x1ff0)) {
+        goto do_read;
+    }
+
+    /* TOD access */
+    switch (addr) {
+    case 0x1FF0:
+        /* flags register */
+       goto do_read;
+    case 0x1FF1:
+        /* unused */
+       retval = 0;
+        break;
+    case 0x1FF2:
+        /* alarm seconds */
+       goto do_read;
+    case 0x1FF3:
+        /* alarm minutes */
+       goto do_read;
+    case 0x1FF4:
+        /* alarm hours */
+       goto do_read;
+    case 0x1FF5:
+        /* alarm date */
+       goto do_read;
+    case 0x1FF6:
+        /* interrupts */
+       goto do_read;
+    case 0x1FF7:
+       /* A read resets the watchdog */
+       set_up_watchdog(NVRAM, NVRAM->buffer[0x1FF7]);
+       goto do_read;
+    case 0x1FF8:
+    case 0x07F8:
+        /* control */
+       goto do_read;
+    case 0x1FF9:
+    case 0x07F9:
+        /* seconds (BCD) */
+        get_time(NVRAM, &tm);
+        retval = (NVRAM->buffer[addr] & 0x80) | to_bcd(tm.tm_sec);
+        break;
+    case 0x1FFA:
+    case 0x07FA:
+        /* minutes (BCD) */
+        get_time(NVRAM, &tm);
+        retval = to_bcd(tm.tm_min);
+        break;
+    case 0x1FFB:
+    case 0x07FB:
+        /* hours (BCD) */
+        get_time(NVRAM, &tm);
+        retval = to_bcd(tm.tm_hour);
+        break;
+    case 0x1FFC:
+    case 0x07FC:
+        /* day of the week / century */
+        get_time(NVRAM, &tm);
+        retval = NVRAM->buffer[addr] | tm.tm_wday;
+        break;
+    case 0x1FFD:
+    case 0x07FD:
+        /* date */
+        get_time(NVRAM, &tm);
+        retval = to_bcd(tm.tm_mday);
+        break;
+    case 0x1FFE:
+    case 0x07FE:
+        /* month */
+        get_time(NVRAM, &tm);
+        retval = to_bcd(tm.tm_mon + 1);
+        break;
+    case 0x1FFF:
+    case 0x07FF:
+        /* year */
+        get_time(NVRAM, &tm);
+        retval = to_bcd((tm.tm_year + 1900 - NVRAM->base_year) % 100);
+        break;
+    default:
+        /* Check lock registers state */
+        if (addr >= 0x20 && addr <= 0x2F && (NVRAM->lock & 1))
+            break;
+        if (addr >= 0x30 && addr <= 0x3F && (NVRAM->lock & 2))
+            break;
+    do_read:
+        if (addr < NVRAM->size) {
+            retval = NVRAM->buffer[addr];
+       }
+        break;
+    }
+    if (addr > 0x1FF9 && addr < 0x2000)
+       NVRAM_PRINTF("%s: 0x%08x <= 0x%08x\n", __func__, addr, retval);
+
+    return retval;
+}
+
+/* IO access to NVRAM */
+static void NVRAM_writeb(void *opaque, hwaddr addr, uint64_t val,
+                         unsigned size)
+{
+    M48t59State *NVRAM = opaque;
+
+    NVRAM_PRINTF("%s: 0x%"HWADDR_PRIx" => 0x%"PRIx64"\n", __func__, addr, val);
+    switch (addr) {
+    case 0:
+        NVRAM->addr &= ~0x00FF;
+        NVRAM->addr |= val;
+        break;
+    case 1:
+        NVRAM->addr &= ~0xFF00;
+        NVRAM->addr |= val << 8;
+        break;
+    case 3:
+        m48t59_write(NVRAM, NVRAM->addr, val);
+        NVRAM->addr = 0x0000;
+        break;
+    default:
+        break;
+    }
+}
+
+static uint64_t NVRAM_readb(void *opaque, hwaddr addr, unsigned size)
+{
+    M48t59State *NVRAM = opaque;
+    uint32_t retval;
+
+    switch (addr) {
+    case 3:
+        retval = m48t59_read(NVRAM, NVRAM->addr);
+        break;
+    default:
+        retval = -1;
+        break;
+    }
+    NVRAM_PRINTF("%s: 0x%"HWADDR_PRIx" <= 0x%08x\n", __func__, addr, retval);
+
+    return retval;
+}
+
+static uint64_t nvram_read(void *opaque, hwaddr addr, unsigned size)
+{
+    M48t59State *NVRAM = opaque;
+
+    return m48t59_read(NVRAM, addr);
+}
+
+static void nvram_write(void *opaque, hwaddr addr, uint64_t value,
+                        unsigned size)
+{
+    M48t59State *NVRAM = opaque;
+
+    return m48t59_write(NVRAM, addr, value);
+}
+
+static const MemoryRegionOps nvram_ops = {
+    .read = nvram_read,
+    .write = nvram_write,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 1,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+    .endianness = DEVICE_BIG_ENDIAN,
+};
+
+static const VMStateDescription vmstate_m48t59 = {
+    .name = "m48t59",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8(lock, M48t59State),
+        VMSTATE_UINT16(addr, M48t59State),
+        VMSTATE_VBUFFER_UINT32(buffer, M48t59State, 0, NULL, size),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+void m48t59_reset_common(M48t59State *NVRAM)
+{
+    NVRAM->addr = 0;
+    NVRAM->lock = 0;
+    if (NVRAM->alrm_timer != NULL)
+        timer_del(NVRAM->alrm_timer);
+
+    if (NVRAM->wd_timer != NULL)
+        timer_del(NVRAM->wd_timer);
+}
+
+static void m48t59_reset_sysbus(DeviceState *d)
+{
+    M48txxSysBusState *sys = M48TXX_SYS_BUS(d);
+    M48t59State *NVRAM = &sys->state;
+
+    m48t59_reset_common(NVRAM);
+}
+
+const MemoryRegionOps m48t59_io_ops = {
+    .read = NVRAM_readb,
+    .write = NVRAM_writeb,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+/* Initialisation routine */
+Nvram *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
+                   uint32_t io_base, uint16_t size, int base_year,
+                   int model)
+{
+    DeviceState *dev;
+    SysBusDevice *s;
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(m48txx_sysbus_info); i++) {
+        if (m48txx_sysbus_info[i].size != size ||
+            m48txx_sysbus_info[i].model != model) {
+            continue;
+        }
+
+        dev = qdev_create(NULL, m48txx_sysbus_info[i].bus_name);
+        qdev_prop_set_int32(dev, "base-year", base_year);
+        qdev_init_nofail(dev);
+        s = SYS_BUS_DEVICE(dev);
+        sysbus_connect_irq(s, 0, IRQ);
+        if (io_base != 0) {
+            memory_region_add_subregion(get_system_io(), io_base,
+                                        sysbus_mmio_get_region(s, 1));
+        }
+        if (mem_base != 0) {
+            sysbus_mmio_map(s, 0, mem_base);
+        }
+
+        return NVRAM(s);
+    }
+
+    assert(false);
+    return NULL;
+}
+
+void m48t59_realize_common(M48t59State *s, Error **errp)
+{
+    s->buffer = g_malloc0(s->size);
+    if (s->model == 59) {
+        s->alrm_timer = timer_new_ns(rtc_clock, &alarm_cb, s);
+        s->wd_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &watchdog_cb, s);
+    }
+    qemu_get_timedate(&s->alarm, 0);
+}
+
+static void m48t59_init1(Object *obj)
+{
+    M48txxSysBusDeviceClass *u = M48TXX_SYS_BUS_GET_CLASS(obj);
+    M48txxSysBusState *d = M48TXX_SYS_BUS(obj);
+    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    M48t59State *s = &d->state;
+
+    s->model = u->info.model;
+    s->size = u->info.size;
+    sysbus_init_irq(dev, &s->IRQ);
+
+    memory_region_init_io(&s->iomem, obj, &nvram_ops, s, "m48t59.nvram",
+                          s->size);
+    memory_region_init_io(&d->io, obj, &m48t59_io_ops, s, "m48t59", 4);
+}
+
+static void m48t59_realize(DeviceState *dev, Error **errp)
+{
+    M48txxSysBusState *d = M48TXX_SYS_BUS(dev);
+    M48t59State *s = &d->state;
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_mmio(sbd, &d->io);
+    m48t59_realize_common(s, errp);
+}
+
+static uint32_t m48txx_sysbus_read(Nvram *obj, uint32_t addr)
+{
+    M48txxSysBusState *d = M48TXX_SYS_BUS(obj);
+    return m48t59_read(&d->state, addr);
+}
+
+static void m48txx_sysbus_write(Nvram *obj, uint32_t addr, uint32_t val)
+{
+    M48txxSysBusState *d = M48TXX_SYS_BUS(obj);
+    m48t59_write(&d->state, addr, val);
+}
+
+static void m48txx_sysbus_toggle_lock(Nvram *obj, int lock)
+{
+    M48txxSysBusState *d = M48TXX_SYS_BUS(obj);
+    m48t59_toggle_lock(&d->state, lock);
+}
+
+static Property m48t59_sysbus_properties[] = {
+    DEFINE_PROP_INT32("base-year", M48txxSysBusState, state.base_year, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void m48txx_sysbus_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    NvramClass *nc = NVRAM_CLASS(klass);
+
+    dc->realize = m48t59_realize;
+    dc->reset = m48t59_reset_sysbus;
+    dc->props = m48t59_sysbus_properties;
+    dc->vmsd = &vmstate_m48t59;
+    nc->read = m48txx_sysbus_read;
+    nc->write = m48txx_sysbus_write;
+    nc->toggle_lock = m48txx_sysbus_toggle_lock;
+}
+
+static void m48txx_sysbus_concrete_class_init(ObjectClass *klass, void *data)
+{
+    M48txxSysBusDeviceClass *u = M48TXX_SYS_BUS_CLASS(klass);
+    M48txxInfo *info = data;
+
+    u->info = *info;
+}
+
+static const TypeInfo nvram_info = {
+    .name = TYPE_NVRAM,
+    .parent = TYPE_INTERFACE,
+    .class_size = sizeof(NvramClass),
+};
+
+static const TypeInfo m48txx_sysbus_type_info = {
+    .name = TYPE_M48TXX_SYS_BUS,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(M48txxSysBusState),
+    .instance_init = m48t59_init1,
+    .abstract = true,
+    .class_init = m48txx_sysbus_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_NVRAM },
+        { }
+    }
+};
+
+static void m48t59_register_types(void)
+{
+    TypeInfo sysbus_type_info = {
+        .parent = TYPE_M48TXX_SYS_BUS,
+        .class_size = sizeof(M48txxSysBusDeviceClass),
+        .class_init = m48txx_sysbus_concrete_class_init,
+    };
+    int i;
+
+    type_register_static(&nvram_info);
+    type_register_static(&m48txx_sysbus_type_info);
+
+    for (i = 0; i < ARRAY_SIZE(m48txx_sysbus_info); i++) {
+        sysbus_type_info.name = m48txx_sysbus_info[i].bus_name;
+        sysbus_type_info.class_data = &m48txx_sysbus_info[i];
+        type_register(&sysbus_type_info);
+    }
+}
+
+type_init(m48t59_register_types)
index 6c5a17a020552205e1abf870064cb4df6fdf468f..2aaa5bf1ae2eeb0f25c80a22390cf7dbb9c777d1 100644 (file)
@@ -31,7 +31,7 @@
 #include "qemu/error-report.h"
 #include "qemu/timer.h"
 #include "hw/sparc/sun4m_iommu.h"
-#include "hw/timer/m48t59.h"
+#include "hw/rtc/m48t59.h"
 #include "migration/vmstate.h"
 #include "hw/sparc/sparc32_dma.h"
 #include "hw/block/fdc.h"
index 1ded2a4c9ab3fdf082cc47bdea1c3355ea788c13..955082773b0691c79782db370b463155045a358e 100644 (file)
@@ -36,7 +36,7 @@
 #include "hw/pci-host/sabre.h"
 #include "hw/char/serial.h"
 #include "hw/char/parallel.h"
-#include "hw/timer/m48t59.h"
+#include "hw/rtc/m48t59.h"
 #include "migration/vmstate.h"
 #include "hw/input/i8042.h"
 #include "hw/block/fdc.h"
index af415c8ef8310ca44ee14c984ddfbfc2e700bce0..a57e9b59fca8c94d6f000ce14822e14966b61b85 100644 (file)
@@ -24,9 +24,6 @@ config M41T80
     bool
     depends on I2C
 
-config M48T59
-    bool
-
 config TWL92230
     bool
     depends on I2C
index b0159189cf34e75206b2283e7945b9bc1a355212..fe2d1fbc4040b8efe3f7f1645565269be184693b 100644 (file)
@@ -7,10 +7,6 @@ common-obj-$(CONFIG_DS1338) += ds1338.o
 common-obj-$(CONFIG_HPET) += hpet.o
 common-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
 common-obj-$(CONFIG_M41T80) += m41t80.o
-common-obj-$(CONFIG_M48T59) += m48t59.o
-ifeq ($(CONFIG_ISA_BUS),y)
-common-obj-$(CONFIG_M48T59) += m48t59-isa.o
-endif
 common-obj-$(CONFIG_PUV3) += puv3_ost.o
 common-obj-$(CONFIG_TWL92230) += twl92230.o
 common-obj-$(CONFIG_XILINX) += xilinx_timer.o
diff --git a/hw/timer/m48t59-internal.h b/hw/timer/m48t59-internal.h
deleted file mode 100644 (file)
index 4d4f2a6..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * QEMU M48T59 and M48T08 NVRAM emulation (common header)
- *
- * Copyright (c) 2003-2005, 2007 Jocelyn Mayer
- * Copyright (c) 2013 Hervé Poussineau
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef HW_M48T59_INTERNAL_H
-#define HW_M48T59_INTERNAL_H
-
-#define M48T59_DEBUG 0
-
-#define NVRAM_PRINTF(fmt, ...) do { \
-    if (M48T59_DEBUG) { printf(fmt , ## __VA_ARGS__); } } while (0)
-
-/*
- * The M48T02, M48T08 and M48T59 chips are very similar. The newer '59 has
- * alarm and a watchdog timer and related control registers. In the
- * PPC platform there is also a nvram lock function.
- */
-
-typedef struct M48txxInfo {
-    const char *bus_name;
-    uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
-    uint32_t size;
-} M48txxInfo;
-
-typedef struct M48t59State {
-    /* Hardware parameters */
-    qemu_irq IRQ;
-    MemoryRegion iomem;
-    uint32_t size;
-    int32_t base_year;
-    /* RTC management */
-    time_t   time_offset;
-    time_t   stop_time;
-    /* Alarm & watchdog */
-    struct tm alarm;
-    QEMUTimer *alrm_timer;
-    QEMUTimer *wd_timer;
-    /* NVRAM storage */
-    uint8_t *buffer;
-    /* Model parameters */
-    uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
-    /* NVRAM storage */
-    uint16_t addr;
-    uint8_t  lock;
-} M48t59State;
-
-uint32_t m48t59_read(M48t59State *NVRAM, uint32_t addr);
-void m48t59_write(M48t59State *NVRAM, uint32_t addr, uint32_t val);
-void m48t59_reset_common(M48t59State *NVRAM);
-void m48t59_realize_common(M48t59State *s, Error **errp);
-
-static inline void m48t59_toggle_lock(M48t59State *NVRAM, int lock)
-{
-    NVRAM->lock ^= 1 << lock;
-}
-
-extern const MemoryRegionOps m48t59_io_ops;
-
-#endif /* HW_M48T59_INTERNAL_H */
diff --git a/hw/timer/m48t59-isa.c b/hw/timer/m48t59-isa.c
deleted file mode 100644 (file)
index 5e5432a..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * QEMU M48T59 and M48T08 NVRAM emulation (ISA bus interface
- *
- * Copyright (c) 2003-2005, 2007 Jocelyn Mayer
- * Copyright (c) 2013 Hervé Poussineau
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "hw/isa/isa.h"
-#include "hw/qdev-properties.h"
-#include "hw/timer/m48t59.h"
-#include "m48t59-internal.h"
-#include "qemu/module.h"
-
-#define TYPE_M48TXX_ISA "isa-m48txx"
-#define M48TXX_ISA_GET_CLASS(obj) \
-    OBJECT_GET_CLASS(M48txxISADeviceClass, (obj), TYPE_M48TXX_ISA)
-#define M48TXX_ISA_CLASS(klass) \
-    OBJECT_CLASS_CHECK(M48txxISADeviceClass, (klass), TYPE_M48TXX_ISA)
-#define M48TXX_ISA(obj) \
-    OBJECT_CHECK(M48txxISAState, (obj), TYPE_M48TXX_ISA)
-
-typedef struct M48txxISAState {
-    ISADevice parent_obj;
-    M48t59State state;
-    uint32_t io_base;
-    MemoryRegion io;
-} M48txxISAState;
-
-typedef struct M48txxISADeviceClass {
-    ISADeviceClass parent_class;
-    M48txxInfo info;
-} M48txxISADeviceClass;
-
-static M48txxInfo m48txx_isa_info[] = {
-    {
-        .bus_name = "isa-m48t59",
-        .model = 59,
-        .size = 0x2000,
-    }
-};
-
-Nvram *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
-                       int base_year, int model)
-{
-    DeviceState *dev;
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(m48txx_isa_info); i++) {
-        if (m48txx_isa_info[i].size != size ||
-            m48txx_isa_info[i].model != model) {
-            continue;
-        }
-
-        dev = DEVICE(isa_create(bus, m48txx_isa_info[i].bus_name));
-        qdev_prop_set_uint32(dev, "iobase", io_base);
-        qdev_prop_set_int32(dev, "base-year", base_year);
-        qdev_init_nofail(dev);
-        return NVRAM(dev);
-    }
-
-    assert(false);
-    return NULL;
-}
-
-static uint32_t m48txx_isa_read(Nvram *obj, uint32_t addr)
-{
-    M48txxISAState *d = M48TXX_ISA(obj);
-    return m48t59_read(&d->state, addr);
-}
-
-static void m48txx_isa_write(Nvram *obj, uint32_t addr, uint32_t val)
-{
-    M48txxISAState *d = M48TXX_ISA(obj);
-    m48t59_write(&d->state, addr, val);
-}
-
-static void m48txx_isa_toggle_lock(Nvram *obj, int lock)
-{
-    M48txxISAState *d = M48TXX_ISA(obj);
-    m48t59_toggle_lock(&d->state, lock);
-}
-
-static Property m48t59_isa_properties[] = {
-    DEFINE_PROP_INT32("base-year", M48txxISAState, state.base_year, 0),
-    DEFINE_PROP_UINT32("iobase", M48txxISAState, io_base, 0x74),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void m48t59_reset_isa(DeviceState *d)
-{
-    M48txxISAState *isa = M48TXX_ISA(d);
-    M48t59State *NVRAM = &isa->state;
-
-    m48t59_reset_common(NVRAM);
-}
-
-static void m48t59_isa_realize(DeviceState *dev, Error **errp)
-{
-    M48txxISADeviceClass *u = M48TXX_ISA_GET_CLASS(dev);
-    ISADevice *isadev = ISA_DEVICE(dev);
-    M48txxISAState *d = M48TXX_ISA(dev);
-    M48t59State *s = &d->state;
-
-    s->model = u->info.model;
-    s->size = u->info.size;
-    isa_init_irq(isadev, &s->IRQ, 8);
-    m48t59_realize_common(s, errp);
-    memory_region_init_io(&d->io, OBJECT(dev), &m48t59_io_ops, s, "m48t59", 4);
-    if (d->io_base != 0) {
-        isa_register_ioport(isadev, &d->io, d->io_base);
-    }
-}
-
-static void m48txx_isa_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    NvramClass *nc = NVRAM_CLASS(klass);
-
-    dc->realize = m48t59_isa_realize;
-    dc->reset = m48t59_reset_isa;
-    dc->props = m48t59_isa_properties;
-    nc->read = m48txx_isa_read;
-    nc->write = m48txx_isa_write;
-    nc->toggle_lock = m48txx_isa_toggle_lock;
-}
-
-static void m48txx_isa_concrete_class_init(ObjectClass *klass, void *data)
-{
-    M48txxISADeviceClass *u = M48TXX_ISA_CLASS(klass);
-    M48txxInfo *info = data;
-
-    u->info = *info;
-}
-
-static const TypeInfo m48txx_isa_type_info = {
-    .name = TYPE_M48TXX_ISA,
-    .parent = TYPE_ISA_DEVICE,
-    .instance_size = sizeof(M48txxISAState),
-    .abstract = true,
-    .class_init = m48txx_isa_class_init,
-    .interfaces = (InterfaceInfo[]) {
-        { TYPE_NVRAM },
-        { }
-    }
-};
-
-static void m48t59_isa_register_types(void)
-{
-    TypeInfo isa_type_info = {
-        .parent = TYPE_M48TXX_ISA,
-        .class_size = sizeof(M48txxISADeviceClass),
-        .class_init = m48txx_isa_concrete_class_init,
-    };
-    int i;
-
-    type_register_static(&m48txx_isa_type_info);
-
-    for (i = 0; i < ARRAY_SIZE(m48txx_isa_info); i++) {
-        isa_type_info.name = m48txx_isa_info[i].bus_name;
-        isa_type_info.class_data = &m48txx_isa_info[i];
-        type_register(&isa_type_info);
-    }
-}
-
-type_init(m48t59_isa_register_types)
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
deleted file mode 100644 (file)
index a9fc2f9..0000000
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- * QEMU M48T59 and M48T08 NVRAM emulation for PPC PREP and Sparc platforms
- *
- * Copyright (c) 2003-2005, 2007, 2017 Jocelyn Mayer
- * Copyright (c) 2013 Hervé Poussineau
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "hw/irq.h"
-#include "hw/qdev-properties.h"
-#include "hw/timer/m48t59.h"
-#include "qemu/timer.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
-#include "hw/sysbus.h"
-#include "exec/address-spaces.h"
-#include "qemu/bcd.h"
-#include "qemu/module.h"
-
-#include "m48t59-internal.h"
-#include "migration/vmstate.h"
-
-#define TYPE_M48TXX_SYS_BUS "sysbus-m48txx"
-#define M48TXX_SYS_BUS_GET_CLASS(obj) \
-    OBJECT_GET_CLASS(M48txxSysBusDeviceClass, (obj), TYPE_M48TXX_SYS_BUS)
-#define M48TXX_SYS_BUS_CLASS(klass) \
-    OBJECT_CLASS_CHECK(M48txxSysBusDeviceClass, (klass), TYPE_M48TXX_SYS_BUS)
-#define M48TXX_SYS_BUS(obj) \
-    OBJECT_CHECK(M48txxSysBusState, (obj), TYPE_M48TXX_SYS_BUS)
-
-/*
- * Chipset docs:
- * http://www.st.com/stonline/products/literature/ds/2410/m48t02.pdf
- * http://www.st.com/stonline/products/literature/ds/2411/m48t08.pdf
- * http://www.st.com/stonline/products/literature/od/7001/m48t59y.pdf
- */
-
-typedef struct M48txxSysBusState {
-    SysBusDevice parent_obj;
-    M48t59State state;
-    MemoryRegion io;
-} M48txxSysBusState;
-
-typedef struct M48txxSysBusDeviceClass {
-    SysBusDeviceClass parent_class;
-    M48txxInfo info;
-} M48txxSysBusDeviceClass;
-
-static M48txxInfo m48txx_sysbus_info[] = {
-    {
-        .bus_name = "sysbus-m48t02",
-        .model = 2,
-        .size = 0x800,
-    },{
-        .bus_name = "sysbus-m48t08",
-        .model = 8,
-        .size = 0x2000,
-    },{
-        .bus_name = "sysbus-m48t59",
-        .model = 59,
-        .size = 0x2000,
-    }
-};
-
-
-/* Fake timer functions */
-
-/* Alarm management */
-static void alarm_cb (void *opaque)
-{
-    struct tm tm;
-    uint64_t next_time;
-    M48t59State *NVRAM = opaque;
-
-    qemu_set_irq(NVRAM->IRQ, 1);
-    if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 &&
-       (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
-       (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
-       (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
-        /* Repeat once a month */
-        qemu_get_timedate(&tm, NVRAM->time_offset);
-        tm.tm_mon++;
-        if (tm.tm_mon == 13) {
-            tm.tm_mon = 1;
-            tm.tm_year++;
-        }
-        next_time = qemu_timedate_diff(&tm) - NVRAM->time_offset;
-    } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
-              (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
-              (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
-              (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
-        /* Repeat once a day */
-        next_time = 24 * 60 * 60;
-    } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
-              (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
-              (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
-              (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
-        /* Repeat once an hour */
-        next_time = 60 * 60;
-    } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
-              (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
-              (NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
-              (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
-        /* Repeat once a minute */
-        next_time = 60;
-    } else {
-        /* Repeat once a second */
-        next_time = 1;
-    }
-    timer_mod(NVRAM->alrm_timer, qemu_clock_get_ns(rtc_clock) +
-                    next_time * 1000);
-    qemu_set_irq(NVRAM->IRQ, 0);
-}
-
-static void set_alarm(M48t59State *NVRAM)
-{
-    int diff;
-    if (NVRAM->alrm_timer != NULL) {
-        timer_del(NVRAM->alrm_timer);
-        diff = qemu_timedate_diff(&NVRAM->alarm) - NVRAM->time_offset;
-        if (diff > 0)
-            timer_mod(NVRAM->alrm_timer, diff * 1000);
-    }
-}
-
-/* RTC management helpers */
-static inline void get_time(M48t59State *NVRAM, struct tm *tm)
-{
-    qemu_get_timedate(tm, NVRAM->time_offset);
-}
-
-static void set_time(M48t59State *NVRAM, struct tm *tm)
-{
-    NVRAM->time_offset = qemu_timedate_diff(tm);
-    set_alarm(NVRAM);
-}
-
-/* Watchdog management */
-static void watchdog_cb (void *opaque)
-{
-    M48t59State *NVRAM = opaque;
-
-    NVRAM->buffer[0x1FF0] |= 0x80;
-    if (NVRAM->buffer[0x1FF7] & 0x80) {
-       NVRAM->buffer[0x1FF7] = 0x00;
-       NVRAM->buffer[0x1FFC] &= ~0x40;
-        /* May it be a hw CPU Reset instead ? */
-        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
-    } else {
-       qemu_set_irq(NVRAM->IRQ, 1);
-       qemu_set_irq(NVRAM->IRQ, 0);
-    }
-}
-
-static void set_up_watchdog(M48t59State *NVRAM, uint8_t value)
-{
-    uint64_t interval; /* in 1/16 seconds */
-
-    NVRAM->buffer[0x1FF0] &= ~0x80;
-    if (NVRAM->wd_timer != NULL) {
-        timer_del(NVRAM->wd_timer);
-        if (value != 0) {
-            interval = (1 << (2 * (value & 0x03))) * ((value >> 2) & 0x1F);
-            timer_mod(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
-                           ((interval * 1000) >> 4));
-        }
-    }
-}
-
-/* Direct access to NVRAM */
-void m48t59_write(M48t59State *NVRAM, uint32_t addr, uint32_t val)
-{
-    struct tm tm;
-    int tmp;
-
-    if (addr > 0x1FF8 && addr < 0x2000)
-       NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val);
-
-    /* check for NVRAM access */
-    if ((NVRAM->model == 2 && addr < 0x7f8) ||
-        (NVRAM->model == 8 && addr < 0x1ff8) ||
-        (NVRAM->model == 59 && addr < 0x1ff0)) {
-        goto do_write;
-    }
-
-    /* TOD access */
-    switch (addr) {
-    case 0x1FF0:
-        /* flags register : read-only */
-        break;
-    case 0x1FF1:
-        /* unused */
-        break;
-    case 0x1FF2:
-        /* alarm seconds */
-        tmp = from_bcd(val & 0x7F);
-        if (tmp >= 0 && tmp <= 59) {
-            NVRAM->alarm.tm_sec = tmp;
-            NVRAM->buffer[0x1FF2] = val;
-            set_alarm(NVRAM);
-        }
-        break;
-    case 0x1FF3:
-        /* alarm minutes */
-        tmp = from_bcd(val & 0x7F);
-        if (tmp >= 0 && tmp <= 59) {
-            NVRAM->alarm.tm_min = tmp;
-            NVRAM->buffer[0x1FF3] = val;
-            set_alarm(NVRAM);
-        }
-        break;
-    case 0x1FF4:
-        /* alarm hours */
-        tmp = from_bcd(val & 0x3F);
-        if (tmp >= 0 && tmp <= 23) {
-            NVRAM->alarm.tm_hour = tmp;
-            NVRAM->buffer[0x1FF4] = val;
-            set_alarm(NVRAM);
-        }
-        break;
-    case 0x1FF5:
-        /* alarm date */
-        tmp = from_bcd(val & 0x3F);
-        if (tmp != 0) {
-            NVRAM->alarm.tm_mday = tmp;
-            NVRAM->buffer[0x1FF5] = val;
-            set_alarm(NVRAM);
-        }
-        break;
-    case 0x1FF6:
-        /* interrupts */
-        NVRAM->buffer[0x1FF6] = val;
-        break;
-    case 0x1FF7:
-        /* watchdog */
-        NVRAM->buffer[0x1FF7] = val;
-        set_up_watchdog(NVRAM, val);
-        break;
-    case 0x1FF8:
-    case 0x07F8:
-        /* control */
-       NVRAM->buffer[addr] = (val & ~0xA0) | 0x90;
-        break;
-    case 0x1FF9:
-    case 0x07F9:
-        /* seconds (BCD) */
-       tmp = from_bcd(val & 0x7F);
-       if (tmp >= 0 && tmp <= 59) {
-           get_time(NVRAM, &tm);
-           tm.tm_sec = tmp;
-           set_time(NVRAM, &tm);
-       }
-        if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) {
-           if (val & 0x80) {
-               NVRAM->stop_time = time(NULL);
-           } else {
-               NVRAM->time_offset += NVRAM->stop_time - time(NULL);
-               NVRAM->stop_time = 0;
-           }
-       }
-        NVRAM->buffer[addr] = val & 0x80;
-        break;
-    case 0x1FFA:
-    case 0x07FA:
-        /* minutes (BCD) */
-       tmp = from_bcd(val & 0x7F);
-       if (tmp >= 0 && tmp <= 59) {
-           get_time(NVRAM, &tm);
-           tm.tm_min = tmp;
-           set_time(NVRAM, &tm);
-       }
-        break;
-    case 0x1FFB:
-    case 0x07FB:
-        /* hours (BCD) */
-       tmp = from_bcd(val & 0x3F);
-       if (tmp >= 0 && tmp <= 23) {
-           get_time(NVRAM, &tm);
-           tm.tm_hour = tmp;
-           set_time(NVRAM, &tm);
-       }
-        break;
-    case 0x1FFC:
-    case 0x07FC:
-        /* day of the week / century */
-       tmp = from_bcd(val & 0x07);
-       get_time(NVRAM, &tm);
-       tm.tm_wday = tmp;
-       set_time(NVRAM, &tm);
-        NVRAM->buffer[addr] = val & 0x40;
-        break;
-    case 0x1FFD:
-    case 0x07FD:
-        /* date (BCD) */
-       tmp = from_bcd(val & 0x3F);
-       if (tmp != 0) {
-           get_time(NVRAM, &tm);
-           tm.tm_mday = tmp;
-           set_time(NVRAM, &tm);
-       }
-        break;
-    case 0x1FFE:
-    case 0x07FE:
-        /* month */
-       tmp = from_bcd(val & 0x1F);
-       if (tmp >= 1 && tmp <= 12) {
-           get_time(NVRAM, &tm);
-           tm.tm_mon = tmp - 1;
-           set_time(NVRAM, &tm);
-       }
-        break;
-    case 0x1FFF:
-    case 0x07FF:
-        /* year */
-       tmp = from_bcd(val);
-       if (tmp >= 0 && tmp <= 99) {
-           get_time(NVRAM, &tm);
-            tm.tm_year = from_bcd(val) + NVRAM->base_year - 1900;
-           set_time(NVRAM, &tm);
-       }
-        break;
-    default:
-        /* Check lock registers state */
-        if (addr >= 0x20 && addr <= 0x2F && (NVRAM->lock & 1))
-            break;
-        if (addr >= 0x30 && addr <= 0x3F && (NVRAM->lock & 2))
-            break;
-    do_write:
-        if (addr < NVRAM->size) {
-            NVRAM->buffer[addr] = val & 0xFF;
-       }
-        break;
-    }
-}
-
-uint32_t m48t59_read(M48t59State *NVRAM, uint32_t addr)
-{
-    struct tm tm;
-    uint32_t retval = 0xFF;
-
-    /* check for NVRAM access */
-    if ((NVRAM->model == 2 && addr < 0x078f) ||
-        (NVRAM->model == 8 && addr < 0x1ff8) ||
-        (NVRAM->model == 59 && addr < 0x1ff0)) {
-        goto do_read;
-    }
-
-    /* TOD access */
-    switch (addr) {
-    case 0x1FF0:
-        /* flags register */
-       goto do_read;
-    case 0x1FF1:
-        /* unused */
-       retval = 0;
-        break;
-    case 0x1FF2:
-        /* alarm seconds */
-       goto do_read;
-    case 0x1FF3:
-        /* alarm minutes */
-       goto do_read;
-    case 0x1FF4:
-        /* alarm hours */
-       goto do_read;
-    case 0x1FF5:
-        /* alarm date */
-       goto do_read;
-    case 0x1FF6:
-        /* interrupts */
-       goto do_read;
-    case 0x1FF7:
-       /* A read resets the watchdog */
-       set_up_watchdog(NVRAM, NVRAM->buffer[0x1FF7]);
-       goto do_read;
-    case 0x1FF8:
-    case 0x07F8:
-        /* control */
-       goto do_read;
-    case 0x1FF9:
-    case 0x07F9:
-        /* seconds (BCD) */
-        get_time(NVRAM, &tm);
-        retval = (NVRAM->buffer[addr] & 0x80) | to_bcd(tm.tm_sec);
-        break;
-    case 0x1FFA:
-    case 0x07FA:
-        /* minutes (BCD) */
-        get_time(NVRAM, &tm);
-        retval = to_bcd(tm.tm_min);
-        break;
-    case 0x1FFB:
-    case 0x07FB:
-        /* hours (BCD) */
-        get_time(NVRAM, &tm);
-        retval = to_bcd(tm.tm_hour);
-        break;
-    case 0x1FFC:
-    case 0x07FC:
-        /* day of the week / century */
-        get_time(NVRAM, &tm);
-        retval = NVRAM->buffer[addr] | tm.tm_wday;
-        break;
-    case 0x1FFD:
-    case 0x07FD:
-        /* date */
-        get_time(NVRAM, &tm);
-        retval = to_bcd(tm.tm_mday);
-        break;
-    case 0x1FFE:
-    case 0x07FE:
-        /* month */
-        get_time(NVRAM, &tm);
-        retval = to_bcd(tm.tm_mon + 1);
-        break;
-    case 0x1FFF:
-    case 0x07FF:
-        /* year */
-        get_time(NVRAM, &tm);
-        retval = to_bcd((tm.tm_year + 1900 - NVRAM->base_year) % 100);
-        break;
-    default:
-        /* Check lock registers state */
-        if (addr >= 0x20 && addr <= 0x2F && (NVRAM->lock & 1))
-            break;
-        if (addr >= 0x30 && addr <= 0x3F && (NVRAM->lock & 2))
-            break;
-    do_read:
-        if (addr < NVRAM->size) {
-            retval = NVRAM->buffer[addr];
-       }
-        break;
-    }
-    if (addr > 0x1FF9 && addr < 0x2000)
-       NVRAM_PRINTF("%s: 0x%08x <= 0x%08x\n", __func__, addr, retval);
-
-    return retval;
-}
-
-/* IO access to NVRAM */
-static void NVRAM_writeb(void *opaque, hwaddr addr, uint64_t val,
-                         unsigned size)
-{
-    M48t59State *NVRAM = opaque;
-
-    NVRAM_PRINTF("%s: 0x%"HWADDR_PRIx" => 0x%"PRIx64"\n", __func__, addr, val);
-    switch (addr) {
-    case 0:
-        NVRAM->addr &= ~0x00FF;
-        NVRAM->addr |= val;
-        break;
-    case 1:
-        NVRAM->addr &= ~0xFF00;
-        NVRAM->addr |= val << 8;
-        break;
-    case 3:
-        m48t59_write(NVRAM, NVRAM->addr, val);
-        NVRAM->addr = 0x0000;
-        break;
-    default:
-        break;
-    }
-}
-
-static uint64_t NVRAM_readb(void *opaque, hwaddr addr, unsigned size)
-{
-    M48t59State *NVRAM = opaque;
-    uint32_t retval;
-
-    switch (addr) {
-    case 3:
-        retval = m48t59_read(NVRAM, NVRAM->addr);
-        break;
-    default:
-        retval = -1;
-        break;
-    }
-    NVRAM_PRINTF("%s: 0x%"HWADDR_PRIx" <= 0x%08x\n", __func__, addr, retval);
-
-    return retval;
-}
-
-static uint64_t nvram_read(void *opaque, hwaddr addr, unsigned size)
-{
-    M48t59State *NVRAM = opaque;
-
-    return m48t59_read(NVRAM, addr);
-}
-
-static void nvram_write(void *opaque, hwaddr addr, uint64_t value,
-                        unsigned size)
-{
-    M48t59State *NVRAM = opaque;
-
-    return m48t59_write(NVRAM, addr, value);
-}
-
-static const MemoryRegionOps nvram_ops = {
-    .read = nvram_read,
-    .write = nvram_write,
-    .impl.min_access_size = 1,
-    .impl.max_access_size = 1,
-    .valid.min_access_size = 1,
-    .valid.max_access_size = 4,
-    .endianness = DEVICE_BIG_ENDIAN,
-};
-
-static const VMStateDescription vmstate_m48t59 = {
-    .name = "m48t59",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT8(lock, M48t59State),
-        VMSTATE_UINT16(addr, M48t59State),
-        VMSTATE_VBUFFER_UINT32(buffer, M48t59State, 0, NULL, size),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-void m48t59_reset_common(M48t59State *NVRAM)
-{
-    NVRAM->addr = 0;
-    NVRAM->lock = 0;
-    if (NVRAM->alrm_timer != NULL)
-        timer_del(NVRAM->alrm_timer);
-
-    if (NVRAM->wd_timer != NULL)
-        timer_del(NVRAM->wd_timer);
-}
-
-static void m48t59_reset_sysbus(DeviceState *d)
-{
-    M48txxSysBusState *sys = M48TXX_SYS_BUS(d);
-    M48t59State *NVRAM = &sys->state;
-
-    m48t59_reset_common(NVRAM);
-}
-
-const MemoryRegionOps m48t59_io_ops = {
-    .read = NVRAM_readb,
-    .write = NVRAM_writeb,
-    .impl = {
-        .min_access_size = 1,
-        .max_access_size = 1,
-    },
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-/* Initialisation routine */
-Nvram *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
-                   uint32_t io_base, uint16_t size, int base_year,
-                   int model)
-{
-    DeviceState *dev;
-    SysBusDevice *s;
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(m48txx_sysbus_info); i++) {
-        if (m48txx_sysbus_info[i].size != size ||
-            m48txx_sysbus_info[i].model != model) {
-            continue;
-        }
-
-        dev = qdev_create(NULL, m48txx_sysbus_info[i].bus_name);
-        qdev_prop_set_int32(dev, "base-year", base_year);
-        qdev_init_nofail(dev);
-        s = SYS_BUS_DEVICE(dev);
-        sysbus_connect_irq(s, 0, IRQ);
-        if (io_base != 0) {
-            memory_region_add_subregion(get_system_io(), io_base,
-                                        sysbus_mmio_get_region(s, 1));
-        }
-        if (mem_base != 0) {
-            sysbus_mmio_map(s, 0, mem_base);
-        }
-
-        return NVRAM(s);
-    }
-
-    assert(false);
-    return NULL;
-}
-
-void m48t59_realize_common(M48t59State *s, Error **errp)
-{
-    s->buffer = g_malloc0(s->size);
-    if (s->model == 59) {
-        s->alrm_timer = timer_new_ns(rtc_clock, &alarm_cb, s);
-        s->wd_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &watchdog_cb, s);
-    }
-    qemu_get_timedate(&s->alarm, 0);
-}
-
-static void m48t59_init1(Object *obj)
-{
-    M48txxSysBusDeviceClass *u = M48TXX_SYS_BUS_GET_CLASS(obj);
-    M48txxSysBusState *d = M48TXX_SYS_BUS(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
-    M48t59State *s = &d->state;
-
-    s->model = u->info.model;
-    s->size = u->info.size;
-    sysbus_init_irq(dev, &s->IRQ);
-
-    memory_region_init_io(&s->iomem, obj, &nvram_ops, s, "m48t59.nvram",
-                          s->size);
-    memory_region_init_io(&d->io, obj, &m48t59_io_ops, s, "m48t59", 4);
-}
-
-static void m48t59_realize(DeviceState *dev, Error **errp)
-{
-    M48txxSysBusState *d = M48TXX_SYS_BUS(dev);
-    M48t59State *s = &d->state;
-    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-
-    sysbus_init_mmio(sbd, &s->iomem);
-    sysbus_init_mmio(sbd, &d->io);
-    m48t59_realize_common(s, errp);
-}
-
-static uint32_t m48txx_sysbus_read(Nvram *obj, uint32_t addr)
-{
-    M48txxSysBusState *d = M48TXX_SYS_BUS(obj);
-    return m48t59_read(&d->state, addr);
-}
-
-static void m48txx_sysbus_write(Nvram *obj, uint32_t addr, uint32_t val)
-{
-    M48txxSysBusState *d = M48TXX_SYS_BUS(obj);
-    m48t59_write(&d->state, addr, val);
-}
-
-static void m48txx_sysbus_toggle_lock(Nvram *obj, int lock)
-{
-    M48txxSysBusState *d = M48TXX_SYS_BUS(obj);
-    m48t59_toggle_lock(&d->state, lock);
-}
-
-static Property m48t59_sysbus_properties[] = {
-    DEFINE_PROP_INT32("base-year", M48txxSysBusState, state.base_year, 0),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void m48txx_sysbus_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    NvramClass *nc = NVRAM_CLASS(klass);
-
-    dc->realize = m48t59_realize;
-    dc->reset = m48t59_reset_sysbus;
-    dc->props = m48t59_sysbus_properties;
-    dc->vmsd = &vmstate_m48t59;
-    nc->read = m48txx_sysbus_read;
-    nc->write = m48txx_sysbus_write;
-    nc->toggle_lock = m48txx_sysbus_toggle_lock;
-}
-
-static void m48txx_sysbus_concrete_class_init(ObjectClass *klass, void *data)
-{
-    M48txxSysBusDeviceClass *u = M48TXX_SYS_BUS_CLASS(klass);
-    M48txxInfo *info = data;
-
-    u->info = *info;
-}
-
-static const TypeInfo nvram_info = {
-    .name = TYPE_NVRAM,
-    .parent = TYPE_INTERFACE,
-    .class_size = sizeof(NvramClass),
-};
-
-static const TypeInfo m48txx_sysbus_type_info = {
-    .name = TYPE_M48TXX_SYS_BUS,
-    .parent = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(M48txxSysBusState),
-    .instance_init = m48t59_init1,
-    .abstract = true,
-    .class_init = m48txx_sysbus_class_init,
-    .interfaces = (InterfaceInfo[]) {
-        { TYPE_NVRAM },
-        { }
-    }
-};
-
-static void m48t59_register_types(void)
-{
-    TypeInfo sysbus_type_info = {
-        .parent = TYPE_M48TXX_SYS_BUS,
-        .class_size = sizeof(M48txxSysBusDeviceClass),
-        .class_init = m48txx_sysbus_concrete_class_init,
-    };
-    int i;
-
-    type_register_static(&nvram_info);
-    type_register_static(&m48txx_sysbus_type_info);
-
-    for (i = 0; i < ARRAY_SIZE(m48txx_sysbus_info); i++) {
-        sysbus_type_info.name = m48txx_sysbus_info[i].bus_name;
-        sysbus_type_info.class_data = &m48txx_sysbus_info[i];
-        type_register(&sysbus_type_info);
-    }
-}
-
-type_init(m48t59_register_types)
diff --git a/include/hw/rtc/m48t59.h b/include/hw/rtc/m48t59.h
new file mode 100644 (file)
index 0000000..e7ea4e8
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * QEMU M48T59 and M48T08 NVRAM emulation
+ *
+ * Copyright (c) 2003-2005, 2007 Jocelyn Mayer
+ * Copyright (c) 2013 Hervé Poussineau
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_RTC_M48T59_H
+#define HW_RTC_M48T59_H
+
+#include "exec/hwaddr.h"
+#include "qom/object.h"
+
+#define TYPE_NVRAM "nvram"
+
+#define NVRAM_CLASS(klass) \
+    OBJECT_CLASS_CHECK(NvramClass, (klass), TYPE_NVRAM)
+#define NVRAM_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(NvramClass, (obj), TYPE_NVRAM)
+#define NVRAM(obj) \
+    INTERFACE_CHECK(Nvram, (obj), TYPE_NVRAM)
+
+typedef struct Nvram Nvram;
+
+typedef struct NvramClass {
+    InterfaceClass parent;
+
+    uint32_t (*read)(Nvram *obj, uint32_t addr);
+    void (*write)(Nvram *obj, uint32_t addr, uint32_t val);
+    void (*toggle_lock)(Nvram *obj, int lock);
+} NvramClass;
+
+Nvram *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
+                       int base_year, int type);
+Nvram *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
+                   uint32_t io_base, uint16_t size, int base_year,
+                   int type);
+
+#endif /* HW_M48T59_H */
diff --git a/include/hw/timer/m48t59.h b/include/hw/timer/m48t59.h
deleted file mode 100644 (file)
index f74854c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef HW_M48T59_H
-#define HW_M48T59_H
-
-#include "exec/hwaddr.h"
-#include "qom/object.h"
-
-#define TYPE_NVRAM "nvram"
-
-#define NVRAM_CLASS(klass) \
-    OBJECT_CLASS_CHECK(NvramClass, (klass), TYPE_NVRAM)
-#define NVRAM_GET_CLASS(obj) \
-    OBJECT_GET_CLASS(NvramClass, (obj), TYPE_NVRAM)
-#define NVRAM(obj) \
-    INTERFACE_CHECK(Nvram, (obj), TYPE_NVRAM)
-
-typedef struct Nvram Nvram;
-
-typedef struct NvramClass {
-    InterfaceClass parent;
-
-    uint32_t (*read)(Nvram *obj, uint32_t addr);
-    void (*write)(Nvram *obj, uint32_t addr, uint32_t val);
-    void (*toggle_lock)(Nvram *obj, int lock);
-} NvramClass;
-
-Nvram *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
-                       int base_year, int type);
-Nvram *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
-                   uint32_t io_base, uint16_t size, int base_year,
-                   int type);
-
-#endif /* HW_M48T59_H */