/*
 * 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 "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)
