/*
 * OSTimer device simulation in PKUnity SoC
 *
 * Copyright (C) 2010-2012 Guan Xuetao
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation, or any later version.
 * See the COPYING file in the top-level directory.
 */
#include "hw/sysbus.h"
#include "hw/ptimer.h"

#undef DEBUG_PUV3
#include "hw/unicore32/puv3.h"

/* puv3 ostimer implementation. */
typedef struct {
    SysBusDevice busdev;
    MemoryRegion iomem;
    QEMUBH *bh;
    qemu_irq irq;
    ptimer_state *ptimer;

    uint32_t reg_OSMR0;
    uint32_t reg_OSCR;
    uint32_t reg_OSSR;
    uint32_t reg_OIER;
} PUV3OSTState;

static uint64_t puv3_ost_read(void *opaque, hwaddr offset,
        unsigned size)
{
    PUV3OSTState *s = opaque;
    uint32_t ret = 0;

    switch (offset) {
    case 0x10: /* Counter Register */
        ret = s->reg_OSMR0 - (uint32_t)ptimer_get_count(s->ptimer);
        break;
    case 0x14: /* Status Register */
        ret = s->reg_OSSR;
        break;
    case 0x1c: /* Interrupt Enable Register */
        ret = s->reg_OIER;
        break;
    default:
        DPRINTF("Bad offset %x\n", (int)offset);
    }
    DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
    return ret;
}

static void puv3_ost_write(void *opaque, hwaddr offset,
        uint64_t value, unsigned size)
{
    PUV3OSTState *s = opaque;

    DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
    switch (offset) {
    case 0x00: /* Match Register 0 */
        s->reg_OSMR0 = value;
        if (s->reg_OSMR0 > s->reg_OSCR) {
            ptimer_set_count(s->ptimer, s->reg_OSMR0 - s->reg_OSCR);
        } else {
            ptimer_set_count(s->ptimer, s->reg_OSMR0 +
                    (0xffffffff - s->reg_OSCR));
        }
        ptimer_run(s->ptimer, 2);
        break;
    case 0x14: /* Status Register */
        assert(value == 0);
        if (s->reg_OSSR) {
            s->reg_OSSR = value;
            qemu_irq_lower(s->irq);
        }
        break;
    case 0x1c: /* Interrupt Enable Register */
        s->reg_OIER = value;
        break;
    default:
        DPRINTF("Bad offset %x\n", (int)offset);
    }
}

static const MemoryRegionOps puv3_ost_ops = {
    .read = puv3_ost_read,
    .write = puv3_ost_write,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void puv3_ost_tick(void *opaque)
{
    PUV3OSTState *s = opaque;

    DPRINTF("ost hit when ptimer counter from 0x%x to 0x%x!\n",
            s->reg_OSCR, s->reg_OSMR0);

    s->reg_OSCR = s->reg_OSMR0;
    if (s->reg_OIER) {
        s->reg_OSSR = 1;
        qemu_irq_raise(s->irq);
    }
}

static int puv3_ost_init(SysBusDevice *dev)
{
    PUV3OSTState *s = FROM_SYSBUS(PUV3OSTState, dev);

    s->reg_OIER = 0;
    s->reg_OSSR = 0;
    s->reg_OSMR0 = 0;
    s->reg_OSCR = 0;

    sysbus_init_irq(dev, &s->irq);

    s->bh = qemu_bh_new(puv3_ost_tick, s);
    s->ptimer = ptimer_init(s->bh);
    ptimer_set_freq(s->ptimer, 50 * 1000 * 1000);

    memory_region_init_io(&s->iomem, OBJECT(s), &puv3_ost_ops, s, "puv3_ost",
            PUV3_REGS_OFFSET);
    sysbus_init_mmio(dev, &s->iomem);

    return 0;
}

static void puv3_ost_class_init(ObjectClass *klass, void *data)
{
    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);

    sdc->init = puv3_ost_init;
}

static const TypeInfo puv3_ost_info = {
    .name = "puv3_ost",
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(PUV3OSTState),
    .class_init = puv3_ost_class_init,
};

static void puv3_ost_register_type(void)
{
    type_register_static(&puv3_ost_info);
}

type_init(puv3_ost_register_type)
