/*
 * 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 "hw/hw.h"
#include "hw/ppc/mac.h"
#include "hw/ppc/mac_dbdma.h"
#include "sysemu/block-backend.h"
#include "sysemu/dma.h"

#include <hw/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_dma_read(BlockBackend *blk,
                          int64_t sector_num, int nb_sectors,
                          void (*cb)(void *opaque, int ret), void *opaque)
{
    DBDMA_io *io = opaque;
    MACIOIDEState *m = io->opaque;
    IDEState *s = idebus_active_if(&m->bus);
    dma_addr_t dma_addr, dma_len;
    void *mem;
    int nsector, remainder;

    qemu_iovec_destroy(&io->iov);
    qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1);

    if (io->remainder_len > 0) {
        /* Return remainder of request */
        int transfer = MIN(io->remainder_len, io->len);

        MACIO_DPRINTF("--- DMA read pop     - bounce addr: %p addr: %"
                      HWADDR_PRIx " remainder_len: %x\n",
                      &io->remainder + (0x200 - transfer), io->addr,
                      io->remainder_len);

        cpu_physical_memory_write(io->addr,
                                  &io->remainder + (0x200 - transfer),
                                  transfer);

        io->remainder_len -= transfer;
        io->len -= transfer;
        io->addr += transfer;

        s->io_buffer_index += transfer;
        s->io_buffer_size -= transfer;

        if (io->remainder_len != 0) {
            /* Still waiting for remainder */
            return;
        }

        if (io->len == 0) {
            MACIO_DPRINTF("--- finished all read processing; go and finish\n");
            cb(opaque, 0);
            return;
        }
    }

    if (s->drive_kind == IDE_CD) {
        sector_num = (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9);
    } else {
        sector_num = ide_get_sector(s) + (s->io_buffer_index >> 9);
    }

    nsector = ((io->len + 0x1ff) >> 9);
    remainder = (nsector << 9) - io->len;

    MACIO_DPRINTF("--- DMA read transfer - addr: %" HWADDR_PRIx " len: %x\n",
                  io->addr, io->len);

    dma_addr = io->addr;
    dma_len = io->len;
    mem = dma_memory_map(&address_space_memory, dma_addr, &dma_len,
                         DMA_DIRECTION_FROM_DEVICE);

    if (!remainder) {
        MACIO_DPRINTF("--- DMA read aligned - addr: %" HWADDR_PRIx
                      " len: %x\n", io->addr, io->len);
        qemu_iovec_add(&io->iov, mem, io->len);
    } else {
        MACIO_DPRINTF("--- DMA read unaligned - addr: %" HWADDR_PRIx
                      " len: %x\n", io->addr, io->len);
        qemu_iovec_add(&io->iov, mem, io->len);

        MACIO_DPRINTF("--- DMA read push    - bounce addr: %p "
                      "remainder_len: %x\n",
                      &io->remainder + 0x200 - remainder, remainder);
        qemu_iovec_add(&io->iov, &io->remainder + 0x200 - remainder,
                       remainder);

        io->remainder_len = remainder;
    }

    s->io_buffer_size -= io->len;
    s->io_buffer_index += io->len;

    io->len = 0;

    MACIO_DPRINTF("--- Block read transfer   - sector_num: %"PRIx64"  "
                  "nsector: %x\n",
                  sector_num, nsector);

    m->aiocb = blk_aio_readv(blk, sector_num, &io->iov, nsector, cb, io);
}

static void pmac_dma_write(BlockBackend *blk,
                         int64_t sector_num, int nb_sectors,
                         void (*cb)(void *opaque, int ret), void *opaque)
{
    DBDMA_io *io = opaque;
    MACIOIDEState *m = io->opaque;
    IDEState *s = idebus_active_if(&m->bus);
    dma_addr_t dma_addr, dma_len;
    void *mem;
    int nsector, remainder;
    int extra = 0;

    qemu_iovec_destroy(&io->iov);
    qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1);

    if (io->remainder_len > 0) {
        /* Return remainder of request */
        int transfer = MIN(io->remainder_len, io->len);

        MACIO_DPRINTF("--- processing write remainder %x\n", transfer);
        cpu_physical_memory_read(io->addr,
                                 &io->remainder + (0x200 - transfer),
                                 transfer);

        io->remainder_len -= transfer;
        io->len -= transfer;
        io->addr += transfer;

        s->io_buffer_index += transfer;
        s->io_buffer_size -= transfer;

        if (io->remainder_len != 0) {
            /* Still waiting for remainder */
            return;
        }

        MACIO_DPRINTF("--> prepending bounce buffer with size 0x200\n");

        /* Sector transfer complete - prepend to request */
        qemu_iovec_add(&io->iov, &io->remainder, 0x200);
        extra = 1;
    }

    if (s->drive_kind == IDE_CD) {
        sector_num = (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9);
    } else {
        sector_num = ide_get_sector(s) + (s->io_buffer_index >> 9);
    }

    nsector = (io->len >> 9);
    remainder = io->len - (nsector << 9);

    MACIO_DPRINTF("--- DMA write transfer - addr: %" HWADDR_PRIx " len: %x\n",
                  io->addr, io->len);
    MACIO_DPRINTF("xxx remainder: %x\n", remainder);
    MACIO_DPRINTF("xxx sector_num: %"PRIx64"   nsector: %x\n",
                  sector_num, nsector);

    dma_addr = io->addr;
    dma_len = io->len;
    mem = dma_memory_map(&address_space_memory, dma_addr, &dma_len,
                         DMA_DIRECTION_TO_DEVICE);

    if (!remainder) {
        MACIO_DPRINTF("--- DMA write aligned - addr: %" HWADDR_PRIx
                      " len: %x\n", io->addr, io->len);
        qemu_iovec_add(&io->iov, mem, io->len);
    } else {
        /* Write up to last complete sector */
        MACIO_DPRINTF("--- DMA write unaligned - addr: %" HWADDR_PRIx
                      " len: %x\n", io->addr, (nsector << 9));
        qemu_iovec_add(&io->iov, mem, (nsector << 9));

        MACIO_DPRINTF("--- DMA write read    - bounce addr: %p "
                      "remainder_len: %x\n", &io->remainder, remainder);
        cpu_physical_memory_read(io->addr + (nsector << 9), &io->remainder,
                                 remainder);

        io->remainder_len = 0x200 - remainder;

        MACIO_DPRINTF("xxx remainder_len: %x\n", io->remainder_len);
    }

    s->io_buffer_size -= ((nsector + extra) << 9);
    s->io_buffer_index += ((nsector + extra) << 9);

    io->len = 0;

    MACIO_DPRINTF("--- Block write transfer   - sector_num: %"PRIx64"  "
                  "nsector: %x\n", sector_num, nsector + extra);

    m->aiocb = blk_aio_writev(blk, sector_num, &io->iov, nsector + extra, cb,
                              io);
}

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

    MACIO_DPRINTF("\ns is %p\n", s);
    MACIO_DPRINTF("io_buffer_index: %x\n", s->io_buffer_index);
    MACIO_DPRINTF("io_buffer_size: %x   packet_transfer_size: %x\n",
                  s->io_buffer_size, s->packet_transfer_size);
    MACIO_DPRINTF("lba: %x\n", s->lba);
    MACIO_DPRINTF("io_addr: %" HWADDR_PRIx "  io_len: %x\n", io->addr,
                  io->len);

    if (ret < 0) {
        MACIO_DPRINTF("THERE WAS AN ERROR!  %d\n", ret);
        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) {
        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);
        cpu_physical_memory_write(io->addr, s->io_buffer, s->io_buffer_size);
        ide_atapi_cmd_ok(s);
        m->dma_active = false;
        goto done;
    }

    /* Calculate number of sectors */
    sector_num = (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9);
    nsector = (io->len + 0x1ff) >> 9;
    remainder = io->len & 0x1ff;

    MACIO_DPRINTF("nsector: %d   remainder: %x\n", nsector, remainder);
    MACIO_DPRINTF("sector: %"PRIx64"   %zx\n", sector_num, io->iov.size / 512);

    pmac_dma_read(s->blk, sector_num, nsector, pmac_ide_atapi_transfer_cb, io);
    return;

done:
    MACIO_DPRINTF("done DMA\n\n");
    block_acct_done(blk_get_stats(s->blk), &s->acct);
    io->dma_end(opaque);

    return;
}

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

    MACIO_DPRINTF("pmac_ide_transfer_cb\n");

    if (ret < 0) {
        MACIO_DPRINTF("DMA error\n");
        m->aiocb = NULL;
        ide_dma_error(s);
        io->remainder_len = 0;
        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 transfer\n");
        s->status = READY_STAT | SEEK_STAT;
        ide_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 */
    sector_num = ide_get_sector(s) + (s->io_buffer_index >> 9);
    nsector = (io->len + 0x1ff) >> 9;
    remainder = io->len & 0x1ff;

    s->nsector -= nsector;

    MACIO_DPRINTF("nsector: %d   remainder: %x\n", nsector, remainder);
    MACIO_DPRINTF("sector: %"PRIx64"   %x\n", sector_num, nsector);

    switch (s->dma_cmd) {
    case IDE_DMA_READ:
        pmac_dma_read(s->blk, sector_num, nsector, pmac_ide_transfer_cb, io);
        break;
    case IDE_DMA_WRITE:
        pmac_dma_write(s->blk, sector_num, nsector, pmac_ide_transfer_cb, io);
        break;
    case IDE_DMA_TRIM:
        MACIO_DPRINTF("TRIM command issued!");
        break;
    }

    return;

done:
    if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
        block_acct_done(blk_get_stats(s->blk), &s->acct);
    }
    io->dma_end(opaque);
}

static void pmac_ide_transfer(DBDMA_io *io)
{
    MACIOIDEState *m = io->opaque;
    IDEState *s = idebus_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;

    if (m->aiocb) {
        blk_drain_all();
    }
}

/* PowerMac IDE memory IO */
static void pmac_ide_writeb (void *opaque,
                             hwaddr addr, uint32_t val)
{
    MACIOIDEState *d = opaque;

    addr = (addr & 0xFFF) >> 4;
    switch (addr) {
    case 1 ... 7:
        ide_ioport_write(&d->bus, addr, val);
        break;
    case 8:
    case 22:
        ide_cmd_write(&d->bus, 0, val);
        break;
    default:
        break;
    }
}

static uint32_t pmac_ide_readb (void *opaque,hwaddr addr)
{
    uint8_t retval;
    MACIOIDEState *d = opaque;

    addr = (addr & 0xFFF) >> 4;
    switch (addr) {
    case 1 ... 7:
        retval = ide_ioport_read(&d->bus, addr);
        break;
    case 8:
    case 22:
        retval = ide_status_read(&d->bus, 0);
        break;
    default:
        retval = 0xFF;
        break;
    }
    return retval;
}

static void pmac_ide_writew (void *opaque,
                             hwaddr addr, uint32_t val)
{
    MACIOIDEState *d = opaque;

    addr = (addr & 0xFFF) >> 4;
    val = bswap16(val);
    if (addr == 0) {
        ide_data_writew(&d->bus, 0, val);
    }
}

static uint32_t pmac_ide_readw (void *opaque,hwaddr addr)
{
    uint16_t retval;
    MACIOIDEState *d = opaque;

    addr = (addr & 0xFFF) >> 4;
    if (addr == 0) {
        retval = ide_data_readw(&d->bus, 0);
    } else {
        retval = 0xFFFF;
    }
    retval = bswap16(retval);
    return retval;
}

static void pmac_ide_writel (void *opaque,
                             hwaddr addr, uint32_t val)
{
    MACIOIDEState *d = opaque;

    addr = (addr & 0xFFF) >> 4;
    val = bswap32(val);
    if (addr == 0) {
        ide_data_writel(&d->bus, 0, val);
    }
}

static uint32_t pmac_ide_readl (void *opaque,hwaddr addr)
{
    uint32_t retval;
    MACIOIDEState *d = opaque;

    addr = (addr & 0xFFF) >> 4;
    if (addr == 0) {
        retval = ide_data_readl(&d->bus, 0);
    } else {
        retval = 0xFFFFFFFF;
    }
    retval = bswap32(retval);
    return retval;
}

static const MemoryRegionOps pmac_ide_ops = {
    .old_mmio = {
        .write = {
            pmac_ide_writeb,
            pmac_ide_writew,
            pmac_ide_writel,
        },
        .read = {
            pmac_ide_readb,
            pmac_ide_readw,
            pmac_ide_readl,
        },
    },
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static const VMStateDescription vmstate_pmac = {
    .name = "ide",
    .version_id = 3,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_IDE_BUS(bus, MACIOIDEState),
        VMSTATE_IDE_DRIVES(bus.ifs, 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(IDEDMA *dma, int x)
{
    return 0;
}

static int32_t ide_nop_int32(IDEDMA *dma, int x)
{
    return 0;
}

static void ide_dbdma_start(IDEDMA *dma, IDEState *s,
                            BlockCompletionFunc *cb)
{
    MACIOIDEState *m = container_of(dma, MACIOIDEState, dma);
    DBDMAState *dbdma = m->dbdma;
    DBDMA_io *io;
    int i;

    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 * 0x200;
    }

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

    for (i = 0; i < DBDMA_CHANNELS; i++) {
        io = &dbdma->channels[i].io;

        if (io->opaque == m) {
            io->remainder_len = 0;
        }
    }

    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_init2(&s->bus, s->irq);

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

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

    ide_bus_new(&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->irq);
    sysbus_init_irq(d, &s->dma_irq);
}

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

    dc->realize = macio_ide_realizefn;
    dc->reset = macio_ide_reset;
    dc->vmsd = &vmstate_pmac;
}

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_create_drive(&s->bus, i, hd_table[i]);
        }
    }
}

void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel)
{
    s->dbdma = dbdma;
    DBDMA_register_channel(dbdma, channel, s->dma_irq,
                           pmac_ide_transfer, pmac_ide_flush, s);
}

type_init(macio_ide_register_types)
