/*
 * 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/irq.h"
#include "hw/qdev-properties.h"
#include "hw/sparc/sparc32_dma.h"
#include "hw/sparc/sun4m_iommu.h"
#include "hw/sysbus.h"
#include "migration/vmstate.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);

    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);
    ESPDMADeviceState *es = SPARC32_ESPDMA_DEVICE(obj);

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

    object_initialize_child(obj, "esp", &es->esp, TYPE_ESP);
}

static void sparc32_espdma_device_realize(DeviceState *dev, Error **errp)
{
    ESPDMADeviceState *es = SPARC32_ESPDMA_DEVICE(dev);
    SysBusESPState *sysbus = ESP(&es->esp);
    ESPState *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;
    sysbus_realize(SYS_BUS_DEVICE(sysbus), &error_fatal);
}

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);
    LEDMADeviceState *ls = SPARC32_LEDMA_DEVICE(obj);

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

    object_initialize_child(obj, "lance", &ls->lance, TYPE_LANCE);
}

static void sparc32_ledma_device_realize(DeviceState *dev, Error **errp)
{
    LEDMADeviceState *s = SPARC32_LEDMA_DEVICE(dev);
    SysBusPCNetState *lance = SYSBUS_PCNET(&s->lance);

    object_property_set_link(OBJECT(lance), "dma", OBJECT(dev), &error_abort);
    sysbus_realize(SYS_BUS_DEVICE(lance), &error_fatal);
}

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 = DEVICE(&s->espdma);
    object_property_set_link(OBJECT(espdma), "iommu", iommu, &error_abort);
    sysbus_realize(SYS_BUS_DEVICE(espdma), &error_fatal);

    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 = DEVICE(&s->ledma);
    object_property_set_link(OBJECT(ledma), "iommu", iommu, &error_abort);
    sysbus_realize(SYS_BUS_DEVICE(ledma), &error_fatal);

    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);

    object_initialize_child(obj, "espdma", &s->espdma,
                            TYPE_SPARC32_ESPDMA_DEVICE);
    object_initialize_child(obj, "ledma", &s->ledma,
                            TYPE_SPARC32_LEDMA_DEVICE);
}

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)
