/*
 * QEMU IDE Emulation: MacIO support.
 *
 * Copyright (c) 2003 Fabrice Bellard
 * Copyright (c) 2006 Openedhand Ltd.
 *
 * 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/ppc/mac_dbdma.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "hw/misc/macio/macio.h"
#include "sysemu/block-backend.h"
#include "sysemu/dma.h"

#include "ide-internal.h"

/* debug MACIO */
// #define DEBUG_MACIO

#ifdef DEBUG_MACIO
static const int debug_macio = 1;
#else
static const int debug_macio = 0;
#endif

#define MACIO_DPRINTF(fmt, ...) do { \
        if (debug_macio) { \
            printf(fmt , ## __VA_ARGS__); \
        } \
    } while (0)


/***********************************************************/
/* MacIO based PowerPC IDE */

#define MACIO_PAGE_SIZE 4096

static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
{
    DBDMA_io *io = opaque;
    MACIOIDEState *m = io->opaque;
    IDEState *s = ide_bus_active_if(&m->bus);
    int64_t offset;

    MACIO_DPRINTF("pmac_ide_atapi_transfer_cb\n");

    if (ret < 0) {
        MACIO_DPRINTF("DMA error: %d\n", ret);
        qemu_sglist_destroy(&s->sg);
        ide_atapi_io_error(s, ret);
        goto done;
    }

    if (!m->dma_active) {
        MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n",
                      s->nsector, io->len, s->status);
        /* data not ready yet, wait for the channel to get restarted */
        io->processing = false;
        return;
    }

    if (s->io_buffer_size <= 0) {
        MACIO_DPRINTF("End of IDE transfer\n");
        qemu_sglist_destroy(&s->sg);
        ide_atapi_cmd_ok(s);
        m->dma_active = false;
        goto done;
    }

    if (io->len == 0) {
        MACIO_DPRINTF("End of DMA transfer\n");
        goto done;
    }

    if (s->lba == -1) {
        /* Non-block ATAPI transfer - just copy to RAM */
        s->io_buffer_size = MIN(s->io_buffer_size, io->len);
        dma_memory_write(&address_space_memory, io->addr, s->io_buffer,
                         s->io_buffer_size, MEMTXATTRS_UNSPECIFIED);
        io->len = 0;
        ide_atapi_cmd_ok(s);
        m->dma_active = false;
        goto done;
    }

    /* Calculate current offset */
    offset = ((int64_t)s->lba << 11) + s->io_buffer_index;

    qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1,
                     &address_space_memory);
    qemu_sglist_add(&s->sg, io->addr, io->len);
    s->io_buffer_size -= io->len;
    s->io_buffer_index += io->len;
    io->len = 0;

    s->bus->dma->aiocb = dma_blk_read(s->blk, &s->sg, offset, 0x1,
                                      pmac_ide_atapi_transfer_cb, io);
    return;

done:
    dma_memory_unmap(&address_space_memory, io->dma_mem, io->dma_len,
                     io->dir, io->dma_len);

    if (ret < 0) {
        block_acct_failed(blk_get_stats(s->blk), &s->acct);
    } else {
        block_acct_done(blk_get_stats(s->blk), &s->acct);
    }

    ide_set_inactive(s, false);
    io->dma_end(opaque);
}

static void pmac_ide_transfer_cb(void *opaque, int ret)
{
    DBDMA_io *io = opaque;
    MACIOIDEState *m = io->opaque;
    IDEState *s = ide_bus_active_if(&m->bus);
    int64_t offset;

    MACIO_DPRINTF("pmac_ide_transfer_cb\n");

    if (ret < 0) {
        MACIO_DPRINTF("DMA error: %d\n", ret);
        qemu_sglist_destroy(&s->sg);
        ide_dma_error(s);
        goto done;
    }

    if (!m->dma_active) {
        MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n",
                      s->nsector, io->len, s->status);
        /* data not ready yet, wait for the channel to get restarted */
        io->processing = false;
        return;
    }

    if (s->io_buffer_size <= 0) {
        MACIO_DPRINTF("End of IDE transfer\n");
        qemu_sglist_destroy(&s->sg);
        s->status = READY_STAT | SEEK_STAT;
        ide_bus_set_irq(s->bus);
        m->dma_active = false;
        goto done;
    }

    if (io->len == 0) {
        MACIO_DPRINTF("End of DMA transfer\n");
        goto done;
    }

    /* Calculate number of sectors */
    offset = (ide_get_sector(s) << 9) + s->io_buffer_index;

    qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1,
                     &address_space_memory);
    qemu_sglist_add(&s->sg, io->addr, io->len);
    s->io_buffer_size -= io->len;
    s->io_buffer_index += io->len;
    io->len = 0;

    switch (s->dma_cmd) {
    case IDE_DMA_READ:
        s->bus->dma->aiocb = dma_blk_read(s->blk, &s->sg, offset, 0x1,
                                          pmac_ide_atapi_transfer_cb, io);
        break;
    case IDE_DMA_WRITE:
        s->bus->dma->aiocb = dma_blk_write(s->blk, &s->sg, offset, 0x1,
                                           pmac_ide_transfer_cb, io);
        break;
    case IDE_DMA_TRIM:
        s->bus->dma->aiocb = dma_blk_io(blk_get_aio_context(s->blk), &s->sg,
                                        offset, 0x1, ide_issue_trim, s,
                                        pmac_ide_transfer_cb, io,
                                        DMA_DIRECTION_TO_DEVICE);
        break;
    default:
        abort();
    }

    return;

done:
    dma_memory_unmap(&address_space_memory, io->dma_mem, io->dma_len,
                     io->dir, io->dma_len);

    if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
        if (ret < 0) {
            block_acct_failed(blk_get_stats(s->blk), &s->acct);
        } else {
            block_acct_done(blk_get_stats(s->blk), &s->acct);
        }
    }

    ide_set_inactive(s, false);
    io->dma_end(opaque);
}

static void pmac_ide_transfer(DBDMA_io *io)
{
    MACIOIDEState *m = io->opaque;
    IDEState *s = ide_bus_active_if(&m->bus);

    MACIO_DPRINTF("\n");

    if (s->drive_kind == IDE_CD) {
        block_acct_start(blk_get_stats(s->blk), &s->acct, io->len,
                         BLOCK_ACCT_READ);

        pmac_ide_atapi_transfer_cb(io, 0);
        return;
    }

    switch (s->dma_cmd) {
    case IDE_DMA_READ:
        block_acct_start(blk_get_stats(s->blk), &s->acct, io->len,
                         BLOCK_ACCT_READ);
        break;
    case IDE_DMA_WRITE:
        block_acct_start(blk_get_stats(s->blk), &s->acct, io->len,
                         BLOCK_ACCT_WRITE);
        break;
    default:
        break;
    }

    pmac_ide_transfer_cb(io, 0);
}

static void pmac_ide_flush(DBDMA_io *io)
{
    MACIOIDEState *m = io->opaque;
    IDEState *s = ide_bus_active_if(&m->bus);

    if (s->bus->dma->aiocb) {
        blk_drain(s->blk);
    }
}

/* PowerMac IDE memory IO */
static uint64_t pmac_ide_read(void *opaque, hwaddr addr, unsigned size)
{
    MACIOIDEState *d = opaque;
    uint64_t retval = 0xffffffff;
    int reg = addr >> 4;

    switch (reg) {
    case 0x0:
        if (size == 1) {
            retval = ide_data_readw(&d->bus, 0) & 0xFF;
        } else if (size == 2) {
            retval = ide_data_readw(&d->bus, 0);
        } else if (size == 4) {
            retval = ide_data_readl(&d->bus, 0);
        }
        break;
    case 0x1 ... 0x7:
        if (size == 1) {
            retval = ide_ioport_read(&d->bus, reg);
        }
        break;
    case 0x8:
    case 0x16:
        if (size == 1) {
            retval = ide_status_read(&d->bus, 0);
        }
        break;
    case 0x20:
        if (size == 4) {
            retval = d->timing_reg;
        }
        break;
    case 0x30:
        /* This is an interrupt state register that only exists
         * in the KeyLargo and later variants. Bit 0x8000_0000
         * latches the DMA interrupt and has to be written to
         * clear. Bit 0x4000_0000 is an image of the disk
         * interrupt. MacOS X relies on this and will hang if
         * we don't provide at least the disk interrupt
         */
        if (size == 4) {
            retval = d->irq_reg;
        }
        break;
    }

    return retval;
}


static void pmac_ide_write(void *opaque, hwaddr addr, uint64_t val,
                           unsigned size)
{
    MACIOIDEState *d = opaque;
    int reg = addr >> 4;

    switch (reg) {
    case 0x0:
        if (size == 2) {
            ide_data_writew(&d->bus, 0, val);
        } else if (size == 4) {
            ide_data_writel(&d->bus, 0, val);
        }
        break;
    case 0x1 ... 0x7:
        if (size == 1) {
            ide_ioport_write(&d->bus, reg, val);
        }
        break;
    case 0x8:
    case 0x16:
        if (size == 1) {
            ide_ctrl_write(&d->bus, 0, val);
        }
        break;
    case 0x20:
        if (size == 4) {
            d->timing_reg = val;
        }
        break;
    case 0x30:
        if (size == 4) {
            if (val & 0x80000000u) {
                d->irq_reg &= 0x7fffffff;
            }
        }
        break;
    }
}

static const MemoryRegionOps pmac_ide_ops = {
    .read = pmac_ide_read,
    .write = pmac_ide_write,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static const VMStateDescription vmstate_pmac = {
    .name = "ide",
    .version_id = 5,
    .minimum_version_id = 0,
    .fields = (const VMStateField[]) {
        VMSTATE_IDE_BUS(bus, MACIOIDEState),
        VMSTATE_IDE_DRIVES(bus.ifs, MACIOIDEState),
        VMSTATE_BOOL(dma_active, MACIOIDEState),
        VMSTATE_UINT32(timing_reg, MACIOIDEState),
        VMSTATE_UINT32(irq_reg, MACIOIDEState),
        VMSTATE_END_OF_LIST()
    }
};

static void macio_ide_reset(DeviceState *dev)
{
    MACIOIDEState *d = MACIO_IDE(dev);

    ide_bus_reset(&d->bus);
}

static int ide_nop_int(const IDEDMA *dma, bool is_write)
{
    return 0;
}

static int32_t ide_nop_int32(const IDEDMA *dma, int32_t l)
{
    return 0;
}

static void ide_dbdma_start(const IDEDMA *dma, IDEState *s,
                            BlockCompletionFunc *cb)
{
    MACIOIDEState *m = container_of(dma, MACIOIDEState, dma);

    s->io_buffer_index = 0;
    if (s->drive_kind == IDE_CD) {
        s->io_buffer_size = s->packet_transfer_size;
    } else {
        s->io_buffer_size = s->nsector * BDRV_SECTOR_SIZE;
    }

    MACIO_DPRINTF("\n\n------------ IDE transfer\n");
    MACIO_DPRINTF("buffer_size: %x   buffer_index: %x\n",
                  s->io_buffer_size, s->io_buffer_index);
    MACIO_DPRINTF("lba: %x    size: %x\n", s->lba, s->io_buffer_size);
    MACIO_DPRINTF("-------------------------\n");

    m->dma_active = true;
    DBDMA_kick(m->dbdma);
}

static const IDEDMAOps dbdma_ops = {
    .start_dma      = ide_dbdma_start,
    .prepare_buf    = ide_nop_int32,
    .rw_buf         = ide_nop_int,
};

static void macio_ide_realizefn(DeviceState *dev, Error **errp)
{
    MACIOIDEState *s = MACIO_IDE(dev);

    ide_bus_init_output_irq(&s->bus,
                            qdev_get_gpio_in(dev, MACIO_IDE_PMAC_IDE_IRQ));

    /* Register DMA callbacks */
    s->dma.ops = &dbdma_ops;
    s->bus.dma = &s->dma;
}

static void pmac_ide_irq(void *opaque, int n, int level)
{
    MACIOIDEState *s = opaque;
    uint32_t mask = 0x80000000u >> n;

    /* We need to reflect the IRQ state in the irq register */
    if (level) {
        s->irq_reg |= mask;
    } else {
        s->irq_reg &= ~mask;
    }

    if (n) {
        qemu_set_irq(s->real_ide_irq, level);
    } else {
        qemu_set_irq(s->real_dma_irq, level);
    }
}

static void macio_ide_initfn(Object *obj)
{
    SysBusDevice *d = SYS_BUS_DEVICE(obj);
    MACIOIDEState *s = MACIO_IDE(obj);

    ide_bus_init(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
    memory_region_init_io(&s->mem, obj, &pmac_ide_ops, s, "pmac-ide", 0x1000);
    sysbus_init_mmio(d, &s->mem);
    sysbus_init_irq(d, &s->real_ide_irq);
    sysbus_init_irq(d, &s->real_dma_irq);

    qdev_init_gpio_in(DEVICE(obj), pmac_ide_irq, MACIO_IDE_PMAC_NIRQS);

    object_property_add_link(obj, "dbdma", TYPE_MAC_DBDMA,
                             (Object **) &s->dbdma,
                             qdev_prop_allow_set_link_before_realize, 0);
}

static Property macio_ide_properties[] = {
    DEFINE_PROP_UINT32("channel", MACIOIDEState, channel, 0),
    DEFINE_PROP_UINT32("addr", MACIOIDEState, addr, -1),
    DEFINE_PROP_END_OF_LIST(),
};

static void macio_ide_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    dc->realize = macio_ide_realizefn;
    device_class_set_legacy_reset(dc, macio_ide_reset);
    device_class_set_props(dc, macio_ide_properties);
    dc->vmsd = &vmstate_pmac;
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}

static const TypeInfo macio_ide_type_info = {
    .name = TYPE_MACIO_IDE,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(MACIOIDEState),
    .instance_init = macio_ide_initfn,
    .class_init = macio_ide_class_init,
};

static void macio_ide_register_types(void)
{
    type_register_static(&macio_ide_type_info);
}

/* hd_table must contain 2 block drivers */
void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table)
{
    int i;

    for (i = 0; i < 2; i++) {
        if (hd_table[i]) {
            ide_bus_create_drive(&s->bus, i, hd_table[i]);
        }
    }
}

void macio_ide_register_dma(MACIOIDEState *s)
{
    DBDMA_register_channel(s->dbdma, s->channel,
                           qdev_get_gpio_in(DEVICE(s), MACIO_IDE_PMAC_DMA_IRQ),
                           pmac_ide_transfer, pmac_ide_flush, s);
}

type_init(macio_ide_register_types)
