/*
 * QEMU Sparc32 DMA controller emulation
 *
 * Copyright (c) 2006 Fabrice Bellard
 *
 * Modifications:
 *  2010-Feb-14 Artyom Tarasenko : reworked irq generation
 *
 * 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/hw.h"
#include "hw/sparc/sparc32_dma.h"
#include "hw/sparc/sun4m_iommu.h"
#include "hw/sysbus.h"
#include "sysemu/dma.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "trace.h"

/*
 * This is the DMA controller part of chip STP2000 (Master I/O), also
 * produced as NCR89C100. See
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
 * and
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/DMA2.txt
 */

#define DMA_SIZE (4 * sizeof(uint32_t))
/* We need the mask, because one instance of the device is not page
   aligned (ledma, start address 0x0010) */
#define DMA_MASK (DMA_SIZE - 1)
/* OBP says 0x20 bytes for ledma, the extras are aliased to espdma */
#define DMA_ETH_SIZE (8 * sizeof(uint32_t))
#define DMA_MAX_REG_OFFSET (2 * DMA_SIZE - 1)

#define DMA_VER 0xa0000000
#define DMA_INTR 1
#define DMA_INTREN 0x10
#define DMA_WRITE_MEM 0x100
#define DMA_EN 0x200
#define DMA_LOADED 0x04000000
#define DMA_DRAIN_FIFO 0x40
#define DMA_RESET 0x80

/* XXX SCSI and ethernet should have different read-only bit masks */
#define DMA_CSR_RO_MASK 0xfe000007

enum {
    GPIO_RESET = 0,
    GPIO_DMA,
};

/* Note: on sparc, the lance 16 bit bus is swapped */
void ledma_memory_read(void *opaque, hwaddr addr,
                       uint8_t *buf, int len, int do_bswap)
{
    DMADeviceState *s = opaque;
    IOMMUState *is = (IOMMUState *)s->iommu;
    int i;

    addr |= s->dmaregs[3];
    trace_ledma_memory_read(addr, len);
    if (do_bswap) {
        dma_memory_read(&is->iommu_as, addr, buf, len);
    } else {
        addr &= ~1;
        len &= ~1;
        dma_memory_read(&is->iommu_as, addr, buf, len);
        for(i = 0; i < len; i += 2) {
            bswap16s((uint16_t *)(buf + i));
        }
    }
}

void ledma_memory_write(void *opaque, hwaddr addr,
                        uint8_t *buf, int len, int do_bswap)
{
    DMADeviceState *s = opaque;
    IOMMUState *is = (IOMMUState *)s->iommu;
    int l, i;
    uint16_t tmp_buf[32];

    addr |= s->dmaregs[3];
    trace_ledma_memory_write(addr, len);
    if (do_bswap) {
        dma_memory_write(&is->iommu_as, addr, buf, len);
    } else {
        addr &= ~1;
        len &= ~1;
        while (len > 0) {
            l = len;
            if (l > sizeof(tmp_buf))
                l = sizeof(tmp_buf);
            for(i = 0; i < l; i += 2) {
                tmp_buf[i >> 1] = bswap16(*(uint16_t *)(buf + i));
            }
            dma_memory_write(&is->iommu_as, addr, tmp_buf, l);
            len -= l;
            buf += l;
            addr += l;
        }
    }
}

static void dma_set_irq(void *opaque, int irq, int level)
{
    DMADeviceState *s = opaque;
    if (level) {
        s->dmaregs[0] |= DMA_INTR;
        if (s->dmaregs[0] & DMA_INTREN) {
            trace_sparc32_dma_set_irq_raise();
            qemu_irq_raise(s->irq);
        }
    } else {
        if (s->dmaregs[0] & DMA_INTR) {
            s->dmaregs[0] &= ~DMA_INTR;
            if (s->dmaregs[0] & DMA_INTREN) {
                trace_sparc32_dma_set_irq_lower();
                qemu_irq_lower(s->irq);
            }
        }
    }
}

void espdma_memory_read(void *opaque, uint8_t *buf, int len)
{
    DMADeviceState *s = opaque;
    IOMMUState *is = (IOMMUState *)s->iommu;

    trace_espdma_memory_read(s->dmaregs[1], len);
    dma_memory_read(&is->iommu_as, s->dmaregs[1], buf, len);
    s->dmaregs[1] += len;
}

void espdma_memory_write(void *opaque, uint8_t *buf, int len)
{
    DMADeviceState *s = opaque;
    IOMMUState *is = (IOMMUState *)s->iommu;

    trace_espdma_memory_write(s->dmaregs[1], len);
    dma_memory_write(&is->iommu_as, s->dmaregs[1], buf, len);
    s->dmaregs[1] += len;
}

static uint64_t dma_mem_read(void *opaque, hwaddr addr,
                             unsigned size)
{
    DMADeviceState *s = opaque;
    uint32_t saddr;

    saddr = (addr & DMA_MASK) >> 2;
    trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
    return s->dmaregs[saddr];
}

static void dma_mem_write(void *opaque, hwaddr addr,
                          uint64_t val, unsigned size)
{
    DMADeviceState *s = opaque;
    uint32_t saddr;

    saddr = (addr & DMA_MASK) >> 2;
    trace_sparc32_dma_mem_writel(addr, s->dmaregs[saddr], val);
    switch (saddr) {
    case 0:
        if (val & DMA_INTREN) {
            if (s->dmaregs[0] & DMA_INTR) {
                trace_sparc32_dma_set_irq_raise();
                qemu_irq_raise(s->irq);
            }
        } else {
            if (s->dmaregs[0] & (DMA_INTR | DMA_INTREN)) {
                trace_sparc32_dma_set_irq_lower();
                qemu_irq_lower(s->irq);
            }
        }
        if (val & DMA_RESET) {
            qemu_irq_raise(s->gpio[GPIO_RESET]);
            qemu_irq_lower(s->gpio[GPIO_RESET]);
        } else if (val & DMA_DRAIN_FIFO) {
            val &= ~DMA_DRAIN_FIFO;
        } else if (val == 0)
            val = DMA_DRAIN_FIFO;

        if (val & DMA_EN && !(s->dmaregs[0] & DMA_EN)) {
            trace_sparc32_dma_enable_raise();
            qemu_irq_raise(s->gpio[GPIO_DMA]);
        } else if (!(val & DMA_EN) && !!(s->dmaregs[0] & DMA_EN)) {
            trace_sparc32_dma_enable_lower();
            qemu_irq_lower(s->gpio[GPIO_DMA]);
        }

        val &= ~DMA_CSR_RO_MASK;
        val |= DMA_VER;
        s->dmaregs[0] = (s->dmaregs[0] & DMA_CSR_RO_MASK) | val;
        break;
    case 1:
        s->dmaregs[0] |= DMA_LOADED;
        /* fall through */
    default:
        s->dmaregs[saddr] = val;
        break;
    }
}

static const MemoryRegionOps dma_mem_ops = {
    .read = dma_mem_read,
    .write = dma_mem_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static void sparc32_dma_device_reset(DeviceState *d)
{
    DMADeviceState *s = SPARC32_DMA_DEVICE(d);

    memset(s->dmaregs, 0, DMA_SIZE);
    s->dmaregs[0] = DMA_VER;
}

static const VMStateDescription vmstate_sparc32_dma_device = {
    .name ="sparc32_dma",
    .version_id = 2,
    .minimum_version_id = 2,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(dmaregs, DMADeviceState, DMA_REGS),
        VMSTATE_END_OF_LIST()
    }
};

static void sparc32_dma_device_init(Object *obj)
{
    DeviceState *dev = DEVICE(obj);
    DMADeviceState *s = SPARC32_DMA_DEVICE(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    sysbus_init_irq(sbd, &s->irq);

    sysbus_init_mmio(sbd, &s->iomem);

    object_property_add_link(OBJECT(dev), "iommu", TYPE_SUN4M_IOMMU,
                             (Object **) &s->iommu,
                             qdev_prop_allow_set_link_before_realize,
                             0, NULL);

    qdev_init_gpio_in(dev, dma_set_irq, 1);
    qdev_init_gpio_out(dev, s->gpio, 2);
}

static void sparc32_dma_device_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->reset = sparc32_dma_device_reset;
    dc->vmsd = &vmstate_sparc32_dma_device;
}

static const TypeInfo sparc32_dma_device_info = {
    .name          = TYPE_SPARC32_DMA_DEVICE,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .abstract      = true,
    .instance_size = sizeof(DMADeviceState),
    .instance_init = sparc32_dma_device_init,
    .class_init    = sparc32_dma_device_class_init,
};

static void sparc32_espdma_device_init(Object *obj)
{
    DMADeviceState *s = SPARC32_DMA_DEVICE(obj);

    memory_region_init_io(&s->iomem, OBJECT(s), &dma_mem_ops, s,
                          "espdma-mmio", DMA_SIZE);
}

static void sparc32_espdma_device_realize(DeviceState *dev, Error **errp)
{
    DeviceState *d;
    SysBusESPState *sysbus;
    ESPState *esp;

    d = qdev_create(NULL, TYPE_ESP);
    object_property_add_child(OBJECT(dev), "esp", OBJECT(d), errp);
    sysbus = ESP_STATE(d);
    esp = &sysbus->esp;
    esp->dma_memory_read = espdma_memory_read;
    esp->dma_memory_write = espdma_memory_write;
    esp->dma_opaque = SPARC32_DMA_DEVICE(dev);
    sysbus->it_shift = 2;
    esp->dma_enabled = 1;
    qdev_init_nofail(d);
}

static void sparc32_espdma_device_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = sparc32_espdma_device_realize;
}

static const TypeInfo sparc32_espdma_device_info = {
    .name          = TYPE_SPARC32_ESPDMA_DEVICE,
    .parent        = TYPE_SPARC32_DMA_DEVICE,
    .instance_size = sizeof(ESPDMADeviceState),
    .instance_init = sparc32_espdma_device_init,
    .class_init    = sparc32_espdma_device_class_init,
};

static void sparc32_ledma_device_init(Object *obj)
{
    DMADeviceState *s = SPARC32_DMA_DEVICE(obj);

    memory_region_init_io(&s->iomem, OBJECT(s), &dma_mem_ops, s,
                          "ledma-mmio", DMA_SIZE);
}

static void sparc32_ledma_device_realize(DeviceState *dev, Error **errp)
{
    DeviceState *d;
    NICInfo *nd = &nd_table[0];

    qemu_check_nic_model(nd, TYPE_LANCE);

    d = qdev_create(NULL, TYPE_LANCE);
    object_property_add_child(OBJECT(dev), "lance", OBJECT(d), errp);
    qdev_set_nic_properties(d, nd);
    qdev_prop_set_ptr(d, "dma", dev);
    qdev_init_nofail(d);
}

static void sparc32_ledma_device_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = sparc32_ledma_device_realize;
}

static const TypeInfo sparc32_ledma_device_info = {
    .name          = TYPE_SPARC32_LEDMA_DEVICE,
    .parent        = TYPE_SPARC32_DMA_DEVICE,
    .instance_size = sizeof(LEDMADeviceState),
    .instance_init = sparc32_ledma_device_init,
    .class_init    = sparc32_ledma_device_class_init,
};

static void sparc32_dma_realize(DeviceState *dev, Error **errp)
{
    SPARC32DMAState *s = SPARC32_DMA(dev);
    DeviceState *espdma, *esp, *ledma, *lance;
    SysBusDevice *sbd;
    Object *iommu;

    iommu = object_resolve_path_type("", TYPE_SUN4M_IOMMU, NULL);
    if (!iommu) {
        error_setg(errp, "unable to locate sun4m IOMMU device");
        return;
    }

    espdma = qdev_create(NULL, TYPE_SPARC32_ESPDMA_DEVICE);
    object_property_set_link(OBJECT(espdma), iommu, "iommu", errp);
    object_property_add_child(OBJECT(s), "espdma", OBJECT(espdma), errp);
    qdev_init_nofail(espdma);

    esp = DEVICE(object_resolve_path_component(OBJECT(espdma), "esp"));
    sbd = SYS_BUS_DEVICE(esp);
    sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(espdma, 0));
    qdev_connect_gpio_out(espdma, 0, qdev_get_gpio_in(esp, 0));
    qdev_connect_gpio_out(espdma, 1, qdev_get_gpio_in(esp, 1));

    sbd = SYS_BUS_DEVICE(espdma);
    memory_region_add_subregion(&s->dmamem, 0x0,
                                sysbus_mmio_get_region(sbd, 0));

    ledma = qdev_create(NULL, TYPE_SPARC32_LEDMA_DEVICE);
    object_property_set_link(OBJECT(ledma), iommu, "iommu", errp);
    object_property_add_child(OBJECT(s), "ledma", OBJECT(ledma), errp);
    qdev_init_nofail(ledma);

    lance = DEVICE(object_resolve_path_component(OBJECT(ledma), "lance"));
    sbd = SYS_BUS_DEVICE(lance);
    sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(ledma, 0));
    qdev_connect_gpio_out(ledma, 0, qdev_get_gpio_in(lance, 0));

    sbd = SYS_BUS_DEVICE(ledma);
    memory_region_add_subregion(&s->dmamem, 0x10,
                                sysbus_mmio_get_region(sbd, 0));

    /* Add ledma alias to handle SunOS 5.7 - Solaris 9 invalid access bug */
    memory_region_init_alias(&s->ledma_alias, OBJECT(dev), "ledma-alias",
                             sysbus_mmio_get_region(sbd, 0), 0x4, 0x4);
    memory_region_add_subregion(&s->dmamem, 0x20, &s->ledma_alias);
}

static void sparc32_dma_init(Object *obj)
{
    SPARC32DMAState *s = SPARC32_DMA(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    memory_region_init(&s->dmamem, OBJECT(s), "dma", DMA_SIZE + DMA_ETH_SIZE);
    sysbus_init_mmio(sbd, &s->dmamem);
}

static void sparc32_dma_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = sparc32_dma_realize;
}

static const TypeInfo sparc32_dma_info = {
    .name          = TYPE_SPARC32_DMA,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(SPARC32DMAState),
    .instance_init = sparc32_dma_init,
    .class_init    = sparc32_dma_class_init,
};


static void sparc32_dma_register_types(void)
{
    type_register_static(&sparc32_dma_device_info);
    type_register_static(&sparc32_espdma_device_info);
    type_register_static(&sparc32_ledma_device_info);
    type_register_static(&sparc32_dma_info);
}

type_init(sparc32_dma_register_types)
