/*
 * Syborg RTC
 *
 * Copyright (c) 2008 CodeSourcery
 *
 * 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 "sysbus.h"
#include "qemu-timer.h"
#include "syborg.h"

enum {
    RTC_ID        = 0,
    RTC_LATCH     = 1,
    RTC_DATA_LOW  = 2,
    RTC_DATA_HIGH = 3
};

typedef struct {
    SysBusDevice busdev;
    int64_t offset;
    int64_t data;
    qemu_irq irq;
} SyborgRTCState;

static uint32_t syborg_rtc_read(void *opaque, target_phys_addr_t offset)
{
    SyborgRTCState *s = (SyborgRTCState *)opaque;
    offset &= 0xfff;
    switch (offset >> 2) {
    case RTC_ID:
        return SYBORG_ID_RTC;
    case RTC_DATA_LOW:
        return (uint32_t)s->data;
    case RTC_DATA_HIGH:
        return (uint32_t)(s->data >> 32);
    default:
        cpu_abort(cpu_single_env, "syborg_rtc_read: Bad offset %x\n",
                  (int)offset);
        return 0;
    }
}

static void syborg_rtc_write(void *opaque, target_phys_addr_t offset, uint32_t value)
{
    SyborgRTCState *s = (SyborgRTCState *)opaque;
    uint64_t now;

    offset &= 0xfff;
    switch (offset >> 2) {
    case RTC_LATCH:
        now = qemu_get_clock_ns(vm_clock);
        if (value >= 4) {
            s->offset = s->data - now;
        } else {
            s->data = now + s->offset;
            while (value) {
                s->data /= 1000;
                value--;
            }
        }
        break;
    case RTC_DATA_LOW:
        s->data = (s->data & ~(uint64_t)0xffffffffu) | value;
        break;
    case RTC_DATA_HIGH:
        s->data = (s->data & 0xffffffffu) | ((uint64_t)value << 32);
        break;
    default:
        cpu_abort(cpu_single_env, "syborg_rtc_write: Bad offset %x\n",
                  (int)offset);
        break;
    }
}

static CPUReadMemoryFunc * const syborg_rtc_readfn[] = {
    syborg_rtc_read,
    syborg_rtc_read,
    syborg_rtc_read
};

static CPUWriteMemoryFunc * const syborg_rtc_writefn[] = {
    syborg_rtc_write,
    syborg_rtc_write,
    syborg_rtc_write
};

static void syborg_rtc_save(QEMUFile *f, void *opaque)
{
    SyborgRTCState *s = opaque;

    qemu_put_be64(f, s->offset);
    qemu_put_be64(f, s->data);
}

static int syborg_rtc_load(QEMUFile *f, void *opaque, int version_id)
{
    SyborgRTCState *s = opaque;

    if (version_id != 1)
        return -EINVAL;

    s->offset = qemu_get_be64(f);
    s->data = qemu_get_be64(f);

    return 0;
}

static int syborg_rtc_init(SysBusDevice *dev)
{
    SyborgRTCState *s = FROM_SYSBUS(SyborgRTCState, dev);
    struct tm tm;
    int iomemtype;

    iomemtype = cpu_register_io_memory(syborg_rtc_readfn,
                                       syborg_rtc_writefn, s,
                                       DEVICE_NATIVE_ENDIAN);
    sysbus_init_mmio(dev, 0x1000, iomemtype);

    qemu_get_timedate(&tm, 0);
    s->offset = (uint64_t)mktime(&tm) * 1000000000;

    register_savevm(&dev->qdev, "syborg_rtc", -1, 1,
                    syborg_rtc_save, syborg_rtc_load, s);
    return 0;
}

static void syborg_rtc_register_devices(void)
{
    sysbus_register_dev("syborg,rtc", sizeof(SyborgRTCState), syborg_rtc_init);
}

device_init(syborg_rtc_register_devices)
