/*
 * PowerMac descriptor-based DMA emulation
 *
 * Copyright (c) 2005-2007 Fabrice Bellard
 * Copyright (c) 2007 Jocelyn Mayer
 * Copyright (c) 2009 Laurent Vivier
 *
 * some parts from linux-2.6.28, arch/powerpc/include/asm/dbdma.h
 *
 *   Definitions for using the Apple Descriptor-Based DMA controller
 *   in Power Macintosh computers.
 *
 *   Copyright (C) 1996 Paul Mackerras.
 *
 * some parts from mol 0.9.71
 *
 *   Descriptor based DMA emulation
 *
 *   Copyright (C) 1998-2004 Samuel Rydh (samuel@ibrium.se)
 *
 * 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/ppc/mac_dbdma.h"
#include "qemu/main-loop.h"
#include "qemu/log.h"
#include "sysemu/dma.h"

/* debug DBDMA */
#define DEBUG_DBDMA 0
#define DEBUG_DBDMA_CHANMASK ((1ull << DBDMA_CHANNELS) - 1)

#define DBDMA_DPRINTF(fmt, ...) do { \
    if (DEBUG_DBDMA) { \
        printf("DBDMA: " fmt , ## __VA_ARGS__); \
    } \
} while (0)

#define DBDMA_DPRINTFCH(ch, fmt, ...) do { \
    if (DEBUG_DBDMA) { \
        if ((1ul << (ch)->channel) & DEBUG_DBDMA_CHANMASK) { \
            printf("DBDMA[%02x]: " fmt , (ch)->channel, ## __VA_ARGS__); \
        } \
    } \
} while (0)

/*
 */

static DBDMAState *dbdma_from_ch(DBDMA_channel *ch)
{
    return container_of(ch, DBDMAState, channels[ch->channel]);
}

#if DEBUG_DBDMA
static void dump_dbdma_cmd(DBDMA_channel *ch, dbdma_cmd *cmd)
{
    DBDMA_DPRINTFCH(ch, "dbdma_cmd %p\n", cmd);
    DBDMA_DPRINTFCH(ch, "    req_count 0x%04x\n", le16_to_cpu(cmd->req_count));
    DBDMA_DPRINTFCH(ch, "    command 0x%04x\n", le16_to_cpu(cmd->command));
    DBDMA_DPRINTFCH(ch, "    phy_addr 0x%08x\n", le32_to_cpu(cmd->phy_addr));
    DBDMA_DPRINTFCH(ch, "    cmd_dep 0x%08x\n", le32_to_cpu(cmd->cmd_dep));
    DBDMA_DPRINTFCH(ch, "    res_count 0x%04x\n", le16_to_cpu(cmd->res_count));
    DBDMA_DPRINTFCH(ch, "    xfer_status 0x%04x\n",
                    le16_to_cpu(cmd->xfer_status));
}
#else
static void dump_dbdma_cmd(DBDMA_channel *ch, dbdma_cmd *cmd)
{
}
#endif
static void dbdma_cmdptr_load(DBDMA_channel *ch)
{
    DBDMA_DPRINTFCH(ch, "dbdma_cmdptr_load 0x%08x\n",
                    ch->regs[DBDMA_CMDPTR_LO]);
    dma_memory_read(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO],
                    &ch->current, sizeof(dbdma_cmd));
}

static void dbdma_cmdptr_save(DBDMA_channel *ch)
{
    DBDMA_DPRINTFCH(ch, "-> update 0x%08x stat=0x%08x, res=0x%04x\n",
                    ch->regs[DBDMA_CMDPTR_LO],
                    le16_to_cpu(ch->current.xfer_status),
                    le16_to_cpu(ch->current.res_count));
    dma_memory_write(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO],
                     &ch->current, sizeof(dbdma_cmd));
}

static void kill_channel(DBDMA_channel *ch)
{
    DBDMA_DPRINTFCH(ch, "kill_channel\n");

    ch->regs[DBDMA_STATUS] |= DEAD;
    ch->regs[DBDMA_STATUS] &= ~ACTIVE;

    qemu_irq_raise(ch->irq);
}

static void conditional_interrupt(DBDMA_channel *ch)
{
    dbdma_cmd *current = &ch->current;
    uint16_t intr;
    uint16_t sel_mask, sel_value;
    uint32_t status;
    int cond;

    DBDMA_DPRINTFCH(ch, "%s\n", __func__);

    intr = le16_to_cpu(current->command) & INTR_MASK;

    switch(intr) {
    case INTR_NEVER:  /* don't interrupt */
        return;
    case INTR_ALWAYS: /* always interrupt */
        qemu_irq_raise(ch->irq);
        DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
        return;
    }

    status = ch->regs[DBDMA_STATUS] & DEVSTAT;

    sel_mask = (ch->regs[DBDMA_INTR_SEL] >> 16) & 0x0f;
    sel_value = ch->regs[DBDMA_INTR_SEL] & 0x0f;

    cond = (status & sel_mask) == (sel_value & sel_mask);

    switch(intr) {
    case INTR_IFSET:  /* intr if condition bit is 1 */
        if (cond) {
            qemu_irq_raise(ch->irq);
            DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
        }
        return;
    case INTR_IFCLR:  /* intr if condition bit is 0 */
        if (!cond) {
            qemu_irq_raise(ch->irq);
            DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
        }
        return;
    }
}

static int conditional_wait(DBDMA_channel *ch)
{
    dbdma_cmd *current = &ch->current;
    uint16_t wait;
    uint16_t sel_mask, sel_value;
    uint32_t status;
    int cond;
    int res = 0;

    wait = le16_to_cpu(current->command) & WAIT_MASK;
    switch(wait) {
    case WAIT_NEVER:  /* don't wait */
        return 0;
    case WAIT_ALWAYS: /* always wait */
        DBDMA_DPRINTFCH(ch, "  [WAIT_ALWAYS]\n");
        return 1;
    }

    status = ch->regs[DBDMA_STATUS] & DEVSTAT;

    sel_mask = (ch->regs[DBDMA_WAIT_SEL] >> 16) & 0x0f;
    sel_value = ch->regs[DBDMA_WAIT_SEL] & 0x0f;

    cond = (status & sel_mask) == (sel_value & sel_mask);

    switch(wait) {
    case WAIT_IFSET:  /* wait if condition bit is 1 */
        if (cond) {
            res = 1;
        }
        DBDMA_DPRINTFCH(ch, "  [WAIT_IFSET=%d]\n", res);
        break;
    case WAIT_IFCLR:  /* wait if condition bit is 0 */
        if (!cond) {
            res = 1;
        }
        DBDMA_DPRINTFCH(ch, "  [WAIT_IFCLR=%d]\n", res);
        break;
    }
    return res;
}

static void next(DBDMA_channel *ch)
{
    uint32_t cp;

    ch->regs[DBDMA_STATUS] &= ~BT;

    cp = ch->regs[DBDMA_CMDPTR_LO];
    ch->regs[DBDMA_CMDPTR_LO] = cp + sizeof(dbdma_cmd);
    dbdma_cmdptr_load(ch);
}

static void branch(DBDMA_channel *ch)
{
    dbdma_cmd *current = &ch->current;

    ch->regs[DBDMA_CMDPTR_LO] = le32_to_cpu(current->cmd_dep);
    ch->regs[DBDMA_STATUS] |= BT;
    dbdma_cmdptr_load(ch);
}

static void conditional_branch(DBDMA_channel *ch)
{
    dbdma_cmd *current = &ch->current;
    uint16_t br;
    uint16_t sel_mask, sel_value;
    uint32_t status;
    int cond;

    /* check if we must branch */

    br = le16_to_cpu(current->command) & BR_MASK;

    switch(br) {
    case BR_NEVER:  /* don't branch */
        next(ch);
        return;
    case BR_ALWAYS: /* always branch */
        DBDMA_DPRINTFCH(ch, "  [BR_ALWAYS]\n");
        branch(ch);
        return;
    }

    status = ch->regs[DBDMA_STATUS] & DEVSTAT;

    sel_mask = (ch->regs[DBDMA_BRANCH_SEL] >> 16) & 0x0f;
    sel_value = ch->regs[DBDMA_BRANCH_SEL] & 0x0f;

    cond = (status & sel_mask) == (sel_value & sel_mask);

    switch(br) {
    case BR_IFSET:  /* branch if condition bit is 1 */
        if (cond) {
            DBDMA_DPRINTFCH(ch, "  [BR_IFSET = 1]\n");
            branch(ch);
        } else {
            DBDMA_DPRINTFCH(ch, "  [BR_IFSET = 0]\n");
            next(ch);
        }
        return;
    case BR_IFCLR:  /* branch if condition bit is 0 */
        if (!cond) {
            DBDMA_DPRINTFCH(ch, "  [BR_IFCLR = 1]\n");
            branch(ch);
        } else {
            DBDMA_DPRINTFCH(ch, "  [BR_IFCLR = 0]\n");
            next(ch);
        }
        return;
    }
}

static void channel_run(DBDMA_channel *ch);

static void dbdma_end(DBDMA_io *io)
{
    DBDMA_channel *ch = io->channel;
    dbdma_cmd *current = &ch->current;

    DBDMA_DPRINTFCH(ch, "%s\n", __func__);

    if (conditional_wait(ch))
        goto wait;

    current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
    current->res_count = cpu_to_le16(io->len);
    dbdma_cmdptr_save(ch);
    if (io->is_last)
        ch->regs[DBDMA_STATUS] &= ~FLUSH;

    conditional_interrupt(ch);
    conditional_branch(ch);

wait:
    /* Indicate that we're ready for a new DMA round */
    ch->io.processing = false;

    if ((ch->regs[DBDMA_STATUS] & RUN) &&
        (ch->regs[DBDMA_STATUS] & ACTIVE))
        channel_run(ch);
}

static void start_output(DBDMA_channel *ch, int key, uint32_t addr,
                        uint16_t req_count, int is_last)
{
    DBDMA_DPRINTFCH(ch, "start_output\n");

    /* KEY_REGS, KEY_DEVICE and KEY_STREAM
     * are not implemented in the mac-io chip
     */

    DBDMA_DPRINTFCH(ch, "addr 0x%x key 0x%x\n", addr, key);
    if (!addr || key > KEY_STREAM3) {
        kill_channel(ch);
        return;
    }

    ch->io.addr = addr;
    ch->io.len = req_count;
    ch->io.is_last = is_last;
    ch->io.dma_end = dbdma_end;
    ch->io.is_dma_out = 1;
    ch->io.processing = true;
    if (ch->rw) {
        ch->rw(&ch->io);
    }
}

static void start_input(DBDMA_channel *ch, int key, uint32_t addr,
                       uint16_t req_count, int is_last)
{
    DBDMA_DPRINTFCH(ch, "start_input\n");

    /* KEY_REGS, KEY_DEVICE and KEY_STREAM
     * are not implemented in the mac-io chip
     */

    DBDMA_DPRINTFCH(ch, "addr 0x%x key 0x%x\n", addr, key);
    if (!addr || key > KEY_STREAM3) {
        kill_channel(ch);
        return;
    }

    ch->io.addr = addr;
    ch->io.len = req_count;
    ch->io.is_last = is_last;
    ch->io.dma_end = dbdma_end;
    ch->io.is_dma_out = 0;
    ch->io.processing = true;
    if (ch->rw) {
        ch->rw(&ch->io);
    }
}

static void load_word(DBDMA_channel *ch, int key, uint32_t addr,
                     uint16_t len)
{
    dbdma_cmd *current = &ch->current;

    DBDMA_DPRINTFCH(ch, "load_word %d bytes, addr=%08x\n", len, addr);

    /* only implements KEY_SYSTEM */

    if (key != KEY_SYSTEM) {
        printf("DBDMA: LOAD_WORD, unimplemented key %x\n", key);
        kill_channel(ch);
        return;
    }

    dma_memory_read(&address_space_memory, addr, &current->cmd_dep, len);

    if (conditional_wait(ch))
        goto wait;

    current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
    dbdma_cmdptr_save(ch);
    ch->regs[DBDMA_STATUS] &= ~FLUSH;

    conditional_interrupt(ch);
    next(ch);

wait:
    DBDMA_kick(dbdma_from_ch(ch));
}

static void store_word(DBDMA_channel *ch, int key, uint32_t addr,
                      uint16_t len)
{
    dbdma_cmd *current = &ch->current;

    DBDMA_DPRINTFCH(ch, "store_word %d bytes, addr=%08x pa=%x\n",
                    len, addr, le32_to_cpu(current->cmd_dep));

    /* only implements KEY_SYSTEM */

    if (key != KEY_SYSTEM) {
        printf("DBDMA: STORE_WORD, unimplemented key %x\n", key);
        kill_channel(ch);
        return;
    }

    dma_memory_write(&address_space_memory, addr, &current->cmd_dep, len);

    if (conditional_wait(ch))
        goto wait;

    current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
    dbdma_cmdptr_save(ch);
    ch->regs[DBDMA_STATUS] &= ~FLUSH;

    conditional_interrupt(ch);
    next(ch);

wait:
    DBDMA_kick(dbdma_from_ch(ch));
}

static void nop(DBDMA_channel *ch)
{
    dbdma_cmd *current = &ch->current;

    if (conditional_wait(ch))
        goto wait;

    current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
    dbdma_cmdptr_save(ch);

    conditional_interrupt(ch);
    conditional_branch(ch);

wait:
    DBDMA_kick(dbdma_from_ch(ch));
}

static void stop(DBDMA_channel *ch)
{
    ch->regs[DBDMA_STATUS] &= ~(ACTIVE);

    /* the stop command does not increment command pointer */
}

static void channel_run(DBDMA_channel *ch)
{
    dbdma_cmd *current = &ch->current;
    uint16_t cmd, key;
    uint16_t req_count;
    uint32_t phy_addr;

    DBDMA_DPRINTFCH(ch, "channel_run\n");
    dump_dbdma_cmd(ch, current);

    /* clear WAKE flag at command fetch */

    ch->regs[DBDMA_STATUS] &= ~WAKE;

    cmd = le16_to_cpu(current->command) & COMMAND_MASK;

    switch (cmd) {
    case DBDMA_NOP:
        nop(ch);
        return;

    case DBDMA_STOP:
        stop(ch);
        return;
    }

    key = le16_to_cpu(current->command) & 0x0700;
    req_count = le16_to_cpu(current->req_count);
    phy_addr = le32_to_cpu(current->phy_addr);

    if (key == KEY_STREAM4) {
        printf("command %x, invalid key 4\n", cmd);
        kill_channel(ch);
        return;
    }

    switch (cmd) {
    case OUTPUT_MORE:
        DBDMA_DPRINTFCH(ch, "* OUTPUT_MORE *\n");
        start_output(ch, key, phy_addr, req_count, 0);
        return;

    case OUTPUT_LAST:
        DBDMA_DPRINTFCH(ch, "* OUTPUT_LAST *\n");
        start_output(ch, key, phy_addr, req_count, 1);
        return;

    case INPUT_MORE:
        DBDMA_DPRINTFCH(ch, "* INPUT_MORE *\n");
        start_input(ch, key, phy_addr, req_count, 0);
        return;

    case INPUT_LAST:
        DBDMA_DPRINTFCH(ch, "* INPUT_LAST *\n");
        start_input(ch, key, phy_addr, req_count, 1);
        return;
    }

    if (key < KEY_REGS) {
        printf("command %x, invalid key %x\n", cmd, key);
        key = KEY_SYSTEM;
    }

    /* for LOAD_WORD and STORE_WORD, req_count is on 3 bits
     * and BRANCH is invalid
     */

    req_count = req_count & 0x0007;
    if (req_count & 0x4) {
        req_count = 4;
        phy_addr &= ~3;
    } else if (req_count & 0x2) {
        req_count = 2;
        phy_addr &= ~1;
    } else
        req_count = 1;

    switch (cmd) {
    case LOAD_WORD:
        DBDMA_DPRINTFCH(ch, "* LOAD_WORD *\n");
        load_word(ch, key, phy_addr, req_count);
        return;

    case STORE_WORD:
        DBDMA_DPRINTFCH(ch, "* STORE_WORD *\n");
        store_word(ch, key, phy_addr, req_count);
        return;
    }
}

static void DBDMA_run(DBDMAState *s)
{
    int channel;

    for (channel = 0; channel < DBDMA_CHANNELS; channel++) {
        DBDMA_channel *ch = &s->channels[channel];
        uint32_t status = ch->regs[DBDMA_STATUS];
        if (!ch->io.processing && (status & RUN) && (status & ACTIVE)) {
            channel_run(ch);
        }
    }
}

static void DBDMA_run_bh(void *opaque)
{
    DBDMAState *s = opaque;

    DBDMA_DPRINTF("-> DBDMA_run_bh\n");
    DBDMA_run(s);
    DBDMA_DPRINTF("<- DBDMA_run_bh\n");
}

void DBDMA_kick(DBDMAState *dbdma)
{
    qemu_bh_schedule(dbdma->bh);
}

void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
                            DBDMA_rw rw, DBDMA_flush flush,
                            void *opaque)
{
    DBDMAState *s = dbdma;
    DBDMA_channel *ch = &s->channels[nchan];

    DBDMA_DPRINTFCH(ch, "DBDMA_register_channel 0x%x\n", nchan);

    assert(rw);
    assert(flush);

    ch->irq = irq;
    ch->rw = rw;
    ch->flush = flush;
    ch->io.opaque = opaque;
}

static void dbdma_control_write(DBDMA_channel *ch)
{
    uint16_t mask, value;
    uint32_t status;
    bool do_flush = false;

    mask = (ch->regs[DBDMA_CONTROL] >> 16) & 0xffff;
    value = ch->regs[DBDMA_CONTROL] & 0xffff;

    /* This is the status register which we'll update
     * appropriately and store back
     */
    status = ch->regs[DBDMA_STATUS];

    /* RUN and PAUSE are bits under SW control only
     * FLUSH and WAKE are set by SW and cleared by HW
     * DEAD, ACTIVE and BT are only under HW control
     *
     * We handle ACTIVE separately at the end of the
     * logic to ensure all cases are covered.
     */

    /* Setting RUN will tentatively activate the channel
     */
    if ((mask & RUN) && (value & RUN)) {
        status |= RUN;
        DBDMA_DPRINTFCH(ch, " Setting RUN !\n");
    }

    /* Clearing RUN 1->0 will stop the channel */
    if ((mask & RUN) && !(value & RUN)) {
        /* This has the side effect of clearing the DEAD bit */
        status &= ~(DEAD | RUN);
        DBDMA_DPRINTFCH(ch, " Clearing RUN !\n");
    }

    /* Setting WAKE wakes up an idle channel if it's running
     *
     * Note: The doc doesn't say so but assume that only works
     * on a channel whose RUN bit is set.
     *
     * We set WAKE in status, it's not terribly useful as it will
     * be cleared on the next command fetch but it seems to mimmic
     * the HW behaviour and is useful for the way we handle
     * ACTIVE further down.
     */
    if ((mask & WAKE) && (value & WAKE) && (status & RUN)) {
        status |= WAKE;
        DBDMA_DPRINTFCH(ch, " Setting WAKE !\n");
    }

    /* PAUSE being set will deactivate (or prevent activation)
     * of the channel. We just copy it over for now, ACTIVE will
     * be re-evaluated later.
     */
    if (mask & PAUSE) {
        status = (status & ~PAUSE) | (value & PAUSE);
        DBDMA_DPRINTFCH(ch, " %sing PAUSE !\n",
                        (value & PAUSE) ? "sett" : "clear");
    }

    /* FLUSH is its own thing */
    if ((mask & FLUSH) && (value & FLUSH))  {
        DBDMA_DPRINTFCH(ch, " Setting FLUSH !\n");
        /* We set flush directly in the status register, we do *NOT*
         * set it in "status" so that it gets naturally cleared when
         * we update the status register further down. That way it
         * will be set only during the HW flush operation so it is
         * visible to any completions happening during that time.
         */
        ch->regs[DBDMA_STATUS] |= FLUSH;
        do_flush = true;
    }

    /* If either RUN or PAUSE is clear, so should ACTIVE be,
     * otherwise, ACTIVE will be set if we modified RUN, PAUSE or
     * set WAKE. That means that PAUSE was just cleared, RUN was
     * just set or WAKE was just set.
     */
    if ((status & PAUSE) || !(status & RUN)) {
        status &= ~ACTIVE;
        DBDMA_DPRINTFCH(ch, "  -> ACTIVE down !\n");

        /* We stopped processing, we want the underlying HW command
         * to complete *before* we clear the ACTIVE bit. Otherwise
         * we can get into a situation where the command status will
         * have RUN or ACTIVE not set which is going to confuse the
         * MacOS driver.
         */
        do_flush = true;
    } else if (mask & (RUN | PAUSE)) {
        status |= ACTIVE;
        DBDMA_DPRINTFCH(ch, " -> ACTIVE up !\n");
    } else if ((mask & WAKE) && (value & WAKE)) {
        status |= ACTIVE;
        DBDMA_DPRINTFCH(ch, " -> ACTIVE up !\n");
    }

    DBDMA_DPRINTFCH(ch, " new status=0x%08x\n", status);

    /* If we need to flush the underlying HW, do it now, this happens
     * both on FLUSH commands and when stopping the channel for safety.
     */
    if (do_flush && ch->flush) {
        ch->flush(&ch->io);
    }

    /* Finally update the status register image */
    ch->regs[DBDMA_STATUS] = status;

    /* If active, make sure the BH gets to run */
    if (status & ACTIVE) {
        DBDMA_kick(dbdma_from_ch(ch));
    }
}

static void dbdma_write(void *opaque, hwaddr addr,
                        uint64_t value, unsigned size)
{
    int channel = addr >> DBDMA_CHANNEL_SHIFT;
    DBDMAState *s = opaque;
    DBDMA_channel *ch = &s->channels[channel];
    int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;

    DBDMA_DPRINTFCH(ch, "writel 0x" TARGET_FMT_plx " <= 0x%08"PRIx64"\n",
                    addr, value);
    DBDMA_DPRINTFCH(ch, "channel 0x%x reg 0x%x\n",
                    (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);

    /* cmdptr cannot be modified if channel is ACTIVE */

    if (reg == DBDMA_CMDPTR_LO && (ch->regs[DBDMA_STATUS] & ACTIVE)) {
        return;
    }

    ch->regs[reg] = value;

    switch(reg) {
    case DBDMA_CONTROL:
        dbdma_control_write(ch);
        break;
    case DBDMA_CMDPTR_LO:
        /* 16-byte aligned */
        ch->regs[DBDMA_CMDPTR_LO] &= ~0xf;
        dbdma_cmdptr_load(ch);
        break;
    case DBDMA_STATUS:
    case DBDMA_INTR_SEL:
    case DBDMA_BRANCH_SEL:
    case DBDMA_WAIT_SEL:
        /* nothing to do */
        break;
    case DBDMA_XFER_MODE:
    case DBDMA_CMDPTR_HI:
    case DBDMA_DATA2PTR_HI:
    case DBDMA_DATA2PTR_LO:
    case DBDMA_ADDRESS_HI:
    case DBDMA_BRANCH_ADDR_HI:
    case DBDMA_RES1:
    case DBDMA_RES2:
    case DBDMA_RES3:
    case DBDMA_RES4:
        /* unused */
        break;
    }
}

static uint64_t dbdma_read(void *opaque, hwaddr addr,
                           unsigned size)
{
    uint32_t value;
    int channel = addr >> DBDMA_CHANNEL_SHIFT;
    DBDMAState *s = opaque;
    DBDMA_channel *ch = &s->channels[channel];
    int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;

    value = ch->regs[reg];

    switch(reg) {
    case DBDMA_CONTROL:
        value = ch->regs[DBDMA_STATUS];
        break;
    case DBDMA_STATUS:
    case DBDMA_CMDPTR_LO:
    case DBDMA_INTR_SEL:
    case DBDMA_BRANCH_SEL:
    case DBDMA_WAIT_SEL:
        /* nothing to do */
        break;
    case DBDMA_XFER_MODE:
    case DBDMA_CMDPTR_HI:
    case DBDMA_DATA2PTR_HI:
    case DBDMA_DATA2PTR_LO:
    case DBDMA_ADDRESS_HI:
    case DBDMA_BRANCH_ADDR_HI:
        /* unused */
        value = 0;
        break;
    case DBDMA_RES1:
    case DBDMA_RES2:
    case DBDMA_RES3:
    case DBDMA_RES4:
        /* reserved */
        break;
    }

    DBDMA_DPRINTFCH(ch, "readl 0x" TARGET_FMT_plx " => 0x%08x\n", addr, value);
    DBDMA_DPRINTFCH(ch, "channel 0x%x reg 0x%x\n",
                    (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);

    return value;
}

static const MemoryRegionOps dbdma_ops = {
    .read = dbdma_read,
    .write = dbdma_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static const VMStateDescription vmstate_dbdma_io = {
    .name = "dbdma_io",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64(addr, struct DBDMA_io),
        VMSTATE_INT32(len, struct DBDMA_io),
        VMSTATE_INT32(is_last, struct DBDMA_io),
        VMSTATE_INT32(is_dma_out, struct DBDMA_io),
        VMSTATE_BOOL(processing, struct DBDMA_io),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_dbdma_cmd = {
    .name = "dbdma_cmd",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT16(req_count, dbdma_cmd),
        VMSTATE_UINT16(command, dbdma_cmd),
        VMSTATE_UINT32(phy_addr, dbdma_cmd),
        VMSTATE_UINT32(cmd_dep, dbdma_cmd),
        VMSTATE_UINT16(res_count, dbdma_cmd),
        VMSTATE_UINT16(xfer_status, dbdma_cmd),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_dbdma_channel = {
    .name = "dbdma_channel",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, struct DBDMA_channel, DBDMA_REGS),
        VMSTATE_STRUCT(io, struct DBDMA_channel, 0, vmstate_dbdma_io, DBDMA_io),
        VMSTATE_STRUCT(current, struct DBDMA_channel, 0, vmstate_dbdma_cmd,
                       dbdma_cmd),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_dbdma = {
    .name = "dbdma",
    .version_id = 3,
    .minimum_version_id = 3,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT_ARRAY(channels, DBDMAState, DBDMA_CHANNELS, 1,
                             vmstate_dbdma_channel, DBDMA_channel),
        VMSTATE_END_OF_LIST()
    }
};

static void mac_dbdma_reset(DeviceState *d)
{
    DBDMAState *s = MAC_DBDMA(d);
    int i;

    for (i = 0; i < DBDMA_CHANNELS; i++) {
        memset(s->channels[i].regs, 0, DBDMA_SIZE);
    }
}

static void dbdma_unassigned_rw(DBDMA_io *io)
{
    DBDMA_channel *ch = io->channel;
    dbdma_cmd *current = &ch->current;
    uint16_t cmd;
    qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
                  __func__, ch->channel);
    ch->io.processing = false;

    cmd = le16_to_cpu(current->command) & COMMAND_MASK;
    if (cmd == OUTPUT_MORE || cmd == OUTPUT_LAST ||
        cmd == INPUT_MORE || cmd == INPUT_LAST) {
        current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
        current->res_count = cpu_to_le16(io->len);
        dbdma_cmdptr_save(ch);
    }
}

static void dbdma_unassigned_flush(DBDMA_io *io)
{
    DBDMA_channel *ch = io->channel;
    qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
                  __func__, ch->channel);
}

static void mac_dbdma_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    DBDMAState *s = MAC_DBDMA(obj);
    int i;

    for (i = 0; i < DBDMA_CHANNELS; i++) {
        DBDMA_channel *ch = &s->channels[i];

        ch->rw = dbdma_unassigned_rw;
        ch->flush = dbdma_unassigned_flush;
        ch->channel = i;
        ch->io.channel = ch;
    }

    memory_region_init_io(&s->mem, obj, &dbdma_ops, s, "dbdma", 0x1000);
    sysbus_init_mmio(sbd, &s->mem);
}

static void mac_dbdma_realize(DeviceState *dev, Error **errp)
{
    DBDMAState *s = MAC_DBDMA(dev);

    s->bh = qemu_bh_new(DBDMA_run_bh, s);
}

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

    dc->realize = mac_dbdma_realize;
    dc->reset = mac_dbdma_reset;
    dc->vmsd = &vmstate_dbdma;
}

static const TypeInfo mac_dbdma_type_info = {
    .name = TYPE_MAC_DBDMA,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(DBDMAState),
    .instance_init = mac_dbdma_init,
    .class_init = mac_dbdma_class_init
};

static void mac_dbdma_register_types(void)
{
    type_register_static(&mac_dbdma_type_info);
}

type_init(mac_dbdma_register_types)
