/*
 * QEMU model of the ZynqMP generic DMA
 *
 * Copyright (c) 2014 Xilinx Inc.
 * Copyright (c) 2018 FEIMTECH AB
 *
 * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>,
 *            Francisco Iglesias <francisco.iglesias@feimtech.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/dma/xlnx-zdma.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "qemu/bitops.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qapi/error.h"

#ifndef XLNX_ZDMA_ERR_DEBUG
#define XLNX_ZDMA_ERR_DEBUG 0
#endif

REG32(ZDMA_ERR_CTRL, 0x0)
    FIELD(ZDMA_ERR_CTRL, APB_ERR_RES, 0, 1)
REG32(ZDMA_CH_ISR, 0x100)
    FIELD(ZDMA_CH_ISR, DMA_PAUSE, 11, 1)
    FIELD(ZDMA_CH_ISR, DMA_DONE, 10, 1)
    FIELD(ZDMA_CH_ISR, AXI_WR_DATA, 9, 1)
    FIELD(ZDMA_CH_ISR, AXI_RD_DATA, 8, 1)
    FIELD(ZDMA_CH_ISR, AXI_RD_DST_DSCR, 7, 1)
    FIELD(ZDMA_CH_ISR, AXI_RD_SRC_DSCR, 6, 1)
    FIELD(ZDMA_CH_ISR, IRQ_DST_ACCT_ERR, 5, 1)
    FIELD(ZDMA_CH_ISR, IRQ_SRC_ACCT_ERR, 4, 1)
    FIELD(ZDMA_CH_ISR, BYTE_CNT_OVRFL, 3, 1)
    FIELD(ZDMA_CH_ISR, DST_DSCR_DONE, 2, 1)
    FIELD(ZDMA_CH_ISR, SRC_DSCR_DONE, 1, 1)
    FIELD(ZDMA_CH_ISR, INV_APB, 0, 1)
REG32(ZDMA_CH_IMR, 0x104)
    FIELD(ZDMA_CH_IMR, DMA_PAUSE, 11, 1)
    FIELD(ZDMA_CH_IMR, DMA_DONE, 10, 1)
    FIELD(ZDMA_CH_IMR, AXI_WR_DATA, 9, 1)
    FIELD(ZDMA_CH_IMR, AXI_RD_DATA, 8, 1)
    FIELD(ZDMA_CH_IMR, AXI_RD_DST_DSCR, 7, 1)
    FIELD(ZDMA_CH_IMR, AXI_RD_SRC_DSCR, 6, 1)
    FIELD(ZDMA_CH_IMR, IRQ_DST_ACCT_ERR, 5, 1)
    FIELD(ZDMA_CH_IMR, IRQ_SRC_ACCT_ERR, 4, 1)
    FIELD(ZDMA_CH_IMR, BYTE_CNT_OVRFL, 3, 1)
    FIELD(ZDMA_CH_IMR, DST_DSCR_DONE, 2, 1)
    FIELD(ZDMA_CH_IMR, SRC_DSCR_DONE, 1, 1)
    FIELD(ZDMA_CH_IMR, INV_APB, 0, 1)
REG32(ZDMA_CH_IEN, 0x108)
    FIELD(ZDMA_CH_IEN, DMA_PAUSE, 11, 1)
    FIELD(ZDMA_CH_IEN, DMA_DONE, 10, 1)
    FIELD(ZDMA_CH_IEN, AXI_WR_DATA, 9, 1)
    FIELD(ZDMA_CH_IEN, AXI_RD_DATA, 8, 1)
    FIELD(ZDMA_CH_IEN, AXI_RD_DST_DSCR, 7, 1)
    FIELD(ZDMA_CH_IEN, AXI_RD_SRC_DSCR, 6, 1)
    FIELD(ZDMA_CH_IEN, IRQ_DST_ACCT_ERR, 5, 1)
    FIELD(ZDMA_CH_IEN, IRQ_SRC_ACCT_ERR, 4, 1)
    FIELD(ZDMA_CH_IEN, BYTE_CNT_OVRFL, 3, 1)
    FIELD(ZDMA_CH_IEN, DST_DSCR_DONE, 2, 1)
    FIELD(ZDMA_CH_IEN, SRC_DSCR_DONE, 1, 1)
    FIELD(ZDMA_CH_IEN, INV_APB, 0, 1)
REG32(ZDMA_CH_IDS, 0x10c)
    FIELD(ZDMA_CH_IDS, DMA_PAUSE, 11, 1)
    FIELD(ZDMA_CH_IDS, DMA_DONE, 10, 1)
    FIELD(ZDMA_CH_IDS, AXI_WR_DATA, 9, 1)
    FIELD(ZDMA_CH_IDS, AXI_RD_DATA, 8, 1)
    FIELD(ZDMA_CH_IDS, AXI_RD_DST_DSCR, 7, 1)
    FIELD(ZDMA_CH_IDS, AXI_RD_SRC_DSCR, 6, 1)
    FIELD(ZDMA_CH_IDS, IRQ_DST_ACCT_ERR, 5, 1)
    FIELD(ZDMA_CH_IDS, IRQ_SRC_ACCT_ERR, 4, 1)
    FIELD(ZDMA_CH_IDS, BYTE_CNT_OVRFL, 3, 1)
    FIELD(ZDMA_CH_IDS, DST_DSCR_DONE, 2, 1)
    FIELD(ZDMA_CH_IDS, SRC_DSCR_DONE, 1, 1)
    FIELD(ZDMA_CH_IDS, INV_APB, 0, 1)
REG32(ZDMA_CH_CTRL0, 0x110)
    FIELD(ZDMA_CH_CTRL0, OVR_FETCH, 7, 1)
    FIELD(ZDMA_CH_CTRL0, POINT_TYPE, 6, 1)
    FIELD(ZDMA_CH_CTRL0, MODE, 4, 2)
    FIELD(ZDMA_CH_CTRL0, RATE_CTRL, 3, 1)
    FIELD(ZDMA_CH_CTRL0, CONT_ADDR, 2, 1)
    FIELD(ZDMA_CH_CTRL0, CONT, 1, 1)
REG32(ZDMA_CH_CTRL1, 0x114)
    FIELD(ZDMA_CH_CTRL1, DST_ISSUE, 5, 5)
    FIELD(ZDMA_CH_CTRL1, SRC_ISSUE, 0, 5)
REG32(ZDMA_CH_FCI, 0x118)
    FIELD(ZDMA_CH_FCI, PROG_CELL_CNT, 2, 2)
    FIELD(ZDMA_CH_FCI, SIDE, 1, 1)
    FIELD(ZDMA_CH_FCI, EN, 0, 1)
REG32(ZDMA_CH_STATUS, 0x11c)
    FIELD(ZDMA_CH_STATUS, STATE, 0, 2)
REG32(ZDMA_CH_DATA_ATTR, 0x120)
    FIELD(ZDMA_CH_DATA_ATTR, ARBURST, 26, 2)
    FIELD(ZDMA_CH_DATA_ATTR, ARCACHE, 22, 4)
    FIELD(ZDMA_CH_DATA_ATTR, ARQOS, 18, 4)
    FIELD(ZDMA_CH_DATA_ATTR, ARLEN, 14, 4)
    FIELD(ZDMA_CH_DATA_ATTR, AWBURST, 12, 2)
    FIELD(ZDMA_CH_DATA_ATTR, AWCACHE, 8, 4)
    FIELD(ZDMA_CH_DATA_ATTR, AWQOS, 4, 4)
    FIELD(ZDMA_CH_DATA_ATTR, AWLEN, 0, 4)
REG32(ZDMA_CH_DSCR_ATTR, 0x124)
    FIELD(ZDMA_CH_DSCR_ATTR, AXCOHRNT, 8, 1)
    FIELD(ZDMA_CH_DSCR_ATTR, AXCACHE, 4, 4)
    FIELD(ZDMA_CH_DSCR_ATTR, AXQOS, 0, 4)
REG32(ZDMA_CH_SRC_DSCR_WORD0, 0x128)
REG32(ZDMA_CH_SRC_DSCR_WORD1, 0x12c)
    FIELD(ZDMA_CH_SRC_DSCR_WORD1, MSB, 0, 17)
REG32(ZDMA_CH_SRC_DSCR_WORD2, 0x130)
    FIELD(ZDMA_CH_SRC_DSCR_WORD2, SIZE, 0, 30)
REG32(ZDMA_CH_SRC_DSCR_WORD3, 0x134)
    FIELD(ZDMA_CH_SRC_DSCR_WORD3, CMD, 3, 2)
    FIELD(ZDMA_CH_SRC_DSCR_WORD3, INTR, 2, 1)
    FIELD(ZDMA_CH_SRC_DSCR_WORD3, TYPE, 1, 1)
    FIELD(ZDMA_CH_SRC_DSCR_WORD3, COHRNT, 0, 1)
REG32(ZDMA_CH_DST_DSCR_WORD0, 0x138)
REG32(ZDMA_CH_DST_DSCR_WORD1, 0x13c)
    FIELD(ZDMA_CH_DST_DSCR_WORD1, MSB, 0, 17)
REG32(ZDMA_CH_DST_DSCR_WORD2, 0x140)
    FIELD(ZDMA_CH_DST_DSCR_WORD2, SIZE, 0, 30)
REG32(ZDMA_CH_DST_DSCR_WORD3, 0x144)
    FIELD(ZDMA_CH_DST_DSCR_WORD3, INTR, 2, 1)
    FIELD(ZDMA_CH_DST_DSCR_WORD3, TYPE, 1, 1)
    FIELD(ZDMA_CH_DST_DSCR_WORD3, COHRNT, 0, 1)
REG32(ZDMA_CH_WR_ONLY_WORD0, 0x148)
REG32(ZDMA_CH_WR_ONLY_WORD1, 0x14c)
REG32(ZDMA_CH_WR_ONLY_WORD2, 0x150)
REG32(ZDMA_CH_WR_ONLY_WORD3, 0x154)
REG32(ZDMA_CH_SRC_START_LSB, 0x158)
REG32(ZDMA_CH_SRC_START_MSB, 0x15c)
    FIELD(ZDMA_CH_SRC_START_MSB, ADDR, 0, 17)
REG32(ZDMA_CH_DST_START_LSB, 0x160)
REG32(ZDMA_CH_DST_START_MSB, 0x164)
    FIELD(ZDMA_CH_DST_START_MSB, ADDR, 0, 17)
REG32(ZDMA_CH_RATE_CTRL, 0x18c)
    FIELD(ZDMA_CH_RATE_CTRL, CNT, 0, 12)
REG32(ZDMA_CH_SRC_CUR_PYLD_LSB, 0x168)
REG32(ZDMA_CH_SRC_CUR_PYLD_MSB, 0x16c)
    FIELD(ZDMA_CH_SRC_CUR_PYLD_MSB, ADDR, 0, 17)
REG32(ZDMA_CH_DST_CUR_PYLD_LSB, 0x170)
REG32(ZDMA_CH_DST_CUR_PYLD_MSB, 0x174)
    FIELD(ZDMA_CH_DST_CUR_PYLD_MSB, ADDR, 0, 17)
REG32(ZDMA_CH_SRC_CUR_DSCR_LSB, 0x178)
REG32(ZDMA_CH_SRC_CUR_DSCR_MSB, 0x17c)
    FIELD(ZDMA_CH_SRC_CUR_DSCR_MSB, ADDR, 0, 17)
REG32(ZDMA_CH_DST_CUR_DSCR_LSB, 0x180)
REG32(ZDMA_CH_DST_CUR_DSCR_MSB, 0x184)
    FIELD(ZDMA_CH_DST_CUR_DSCR_MSB, ADDR, 0, 17)
REG32(ZDMA_CH_TOTAL_BYTE, 0x188)
REG32(ZDMA_CH_RATE_CNTL, 0x18c)
    FIELD(ZDMA_CH_RATE_CNTL, CNT, 0, 12)
REG32(ZDMA_CH_IRQ_SRC_ACCT, 0x190)
    FIELD(ZDMA_CH_IRQ_SRC_ACCT, CNT, 0, 8)
REG32(ZDMA_CH_IRQ_DST_ACCT, 0x194)
    FIELD(ZDMA_CH_IRQ_DST_ACCT, CNT, 0, 8)
REG32(ZDMA_CH_DBG0, 0x198)
    FIELD(ZDMA_CH_DBG0, CMN_BUF_FREE, 0, 9)
REG32(ZDMA_CH_DBG1, 0x19c)
    FIELD(ZDMA_CH_DBG1, CMN_BUF_OCC, 0, 9)
REG32(ZDMA_CH_CTRL2, 0x200)
    FIELD(ZDMA_CH_CTRL2, EN, 0, 1)

enum {
    PT_REG = 0,
    PT_MEM = 1,
};

enum {
    CMD_HALT = 1,
    CMD_STOP = 2,
};

enum {
    RW_MODE_RW = 0,
    RW_MODE_WO = 1,
    RW_MODE_RO = 2,
};

enum {
    DTYPE_LINEAR = 0,
    DTYPE_LINKED = 1,
};

enum {
    AXI_BURST_FIXED = 0,
    AXI_BURST_INCR  = 1,
};

static void zdma_ch_imr_update_irq(XlnxZDMA *s)
{
    bool pending;

    pending = s->regs[R_ZDMA_CH_ISR] & ~s->regs[R_ZDMA_CH_IMR];

    qemu_set_irq(s->irq_zdma_ch_imr, pending);
}

static void zdma_ch_isr_postw(RegisterInfo *reg, uint64_t val64)
{
    XlnxZDMA *s = XLNX_ZDMA(reg->opaque);
    zdma_ch_imr_update_irq(s);
}

static uint64_t zdma_ch_ien_prew(RegisterInfo *reg, uint64_t val64)
{
    XlnxZDMA *s = XLNX_ZDMA(reg->opaque);
    uint32_t val = val64;

    s->regs[R_ZDMA_CH_IMR] &= ~val;
    zdma_ch_imr_update_irq(s);
    return 0;
}

static uint64_t zdma_ch_ids_prew(RegisterInfo *reg, uint64_t val64)
{
    XlnxZDMA *s = XLNX_ZDMA(reg->opaque);
    uint32_t val = val64;

    s->regs[R_ZDMA_CH_IMR] |= val;
    zdma_ch_imr_update_irq(s);
    return 0;
}

static void zdma_set_state(XlnxZDMA *s, XlnxZDMAState state)
{
    s->state = state;
    ARRAY_FIELD_DP32(s->regs, ZDMA_CH_STATUS, STATE, state);

    /* Signal error if we have an error condition.  */
    if (s->error) {
        ARRAY_FIELD_DP32(s->regs, ZDMA_CH_STATUS, STATE, 3);
    }
}

static void zdma_src_done(XlnxZDMA *s)
{
    unsigned int cnt;
    cnt = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_IRQ_SRC_ACCT, CNT);
    cnt++;
    ARRAY_FIELD_DP32(s->regs, ZDMA_CH_IRQ_SRC_ACCT, CNT, cnt);
    ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, SRC_DSCR_DONE, true);

    /* Did we overflow?  */
    if (cnt != ARRAY_FIELD_EX32(s->regs, ZDMA_CH_IRQ_SRC_ACCT, CNT)) {
        ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, IRQ_SRC_ACCT_ERR, true);
    }
    zdma_ch_imr_update_irq(s);
}

static void zdma_dst_done(XlnxZDMA *s)
{
    unsigned int cnt;
    cnt = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_IRQ_DST_ACCT, CNT);
    cnt++;
    ARRAY_FIELD_DP32(s->regs, ZDMA_CH_IRQ_DST_ACCT, CNT, cnt);
    ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, DST_DSCR_DONE, true);

    /* Did we overflow?  */
    if (cnt != ARRAY_FIELD_EX32(s->regs, ZDMA_CH_IRQ_DST_ACCT, CNT)) {
        ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, IRQ_DST_ACCT_ERR, true);
    }
    zdma_ch_imr_update_irq(s);
}

static uint64_t zdma_get_regaddr64(XlnxZDMA *s, unsigned int basereg)
{
    uint64_t addr;

    addr = s->regs[basereg + 1];
    addr <<= 32;
    addr |= s->regs[basereg];

    return addr;
}

static void zdma_put_regaddr64(XlnxZDMA *s, unsigned int basereg, uint64_t addr)
{
    s->regs[basereg] = addr;
    s->regs[basereg + 1] = addr >> 32;
}

static void zdma_load_descriptor_reg(XlnxZDMA *s, unsigned int reg,
                                     XlnxZDMADescr *descr)
{
    descr->addr = zdma_get_regaddr64(s, reg);
    descr->size = s->regs[reg + 2];
    descr->attr = s->regs[reg + 3];
}

static bool zdma_load_descriptor(XlnxZDMA *s, uint64_t addr,
                                 XlnxZDMADescr *descr)
{
    /* ZDMA descriptors must be aligned to their own size.  */
    if (addr % sizeof(XlnxZDMADescr)) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "zdma: unaligned descriptor at %" PRIx64,
                      addr);
        memset(descr, 0x0, sizeof(XlnxZDMADescr));
        s->error = true;
        return false;
    }

    descr->addr = address_space_ldq_le(&s->dma_as, addr, s->attr, NULL);
    descr->size = address_space_ldl_le(&s->dma_as, addr + 8, s->attr, NULL);
    descr->attr = address_space_ldl_le(&s->dma_as, addr + 12, s->attr, NULL);
    return true;
}

static void zdma_load_src_descriptor(XlnxZDMA *s)
{
    uint64_t src_addr;
    unsigned int ptype = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, POINT_TYPE);

    if (ptype == PT_REG) {
        zdma_load_descriptor_reg(s, R_ZDMA_CH_SRC_DSCR_WORD0, &s->dsc_src);
        return;
    }

    src_addr = zdma_get_regaddr64(s, R_ZDMA_CH_SRC_CUR_DSCR_LSB);

    if (!zdma_load_descriptor(s, src_addr, &s->dsc_src)) {
        ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, AXI_RD_SRC_DSCR, true);
    }
}

static void zdma_update_descr_addr(XlnxZDMA *s, bool type,
                                   unsigned int basereg)
{
    uint64_t addr, next;

    if (type == DTYPE_LINEAR) {
        addr = zdma_get_regaddr64(s, basereg);
        next = addr + sizeof(s->dsc_dst);
    } else {
        addr = zdma_get_regaddr64(s, basereg);
        addr += sizeof(s->dsc_dst);
        next = address_space_ldq_le(&s->dma_as, addr, s->attr, NULL);
    }

    zdma_put_regaddr64(s, basereg, next);
}

static void zdma_load_dst_descriptor(XlnxZDMA *s)
{
    uint64_t dst_addr;
    unsigned int ptype = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, POINT_TYPE);
    bool dst_type;

    if (ptype == PT_REG) {
        zdma_load_descriptor_reg(s, R_ZDMA_CH_DST_DSCR_WORD0, &s->dsc_dst);
        return;
    }

    dst_addr = zdma_get_regaddr64(s, R_ZDMA_CH_DST_CUR_DSCR_LSB);

    if (!zdma_load_descriptor(s, dst_addr, &s->dsc_dst)) {
        ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, AXI_RD_DST_DSCR, true);
    }

    /* Advance the descriptor pointer.  */
    dst_type = FIELD_EX32(s->dsc_dst.words[3], ZDMA_CH_DST_DSCR_WORD3, TYPE);
    zdma_update_descr_addr(s, dst_type, R_ZDMA_CH_DST_CUR_DSCR_LSB);
}

static void zdma_write_dst(XlnxZDMA *s, uint8_t *buf, uint32_t len)
{
    uint32_t dst_size, dlen;
    bool dst_intr;
    unsigned int ptype = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, POINT_TYPE);
    unsigned int rw_mode = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, MODE);
    unsigned int burst_type = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_DATA_ATTR,
                                               AWBURST);

    /* FIXED burst types are only supported in simple dma mode.  */
    if (ptype != PT_REG) {
        burst_type = AXI_BURST_INCR;
    }

    while (len) {
        dst_size = FIELD_EX32(s->dsc_dst.words[2], ZDMA_CH_DST_DSCR_WORD2,
                              SIZE);
        if (dst_size == 0 && ptype == PT_MEM) {
            zdma_load_dst_descriptor(s);
            dst_size = FIELD_EX32(s->dsc_dst.words[2], ZDMA_CH_DST_DSCR_WORD2,
                                  SIZE);
        }

        /* Match what hardware does by ignoring the dst_size and only using
         * the src size for Simple register mode.  */
        if (ptype == PT_REG && rw_mode != RW_MODE_WO) {
            dst_size = len;
        }

        dst_intr = FIELD_EX32(s->dsc_dst.words[3], ZDMA_CH_DST_DSCR_WORD3,
                              INTR);

        dlen = len > dst_size ? dst_size : len;
        if (burst_type == AXI_BURST_FIXED) {
            if (dlen > (s->cfg.bus_width / 8)) {
                dlen = s->cfg.bus_width / 8;
            }
        }

        address_space_write(&s->dma_as, s->dsc_dst.addr, s->attr, buf, dlen);
        if (burst_type == AXI_BURST_INCR) {
            s->dsc_dst.addr += dlen;
        }
        dst_size -= dlen;
        buf += dlen;
        len -= dlen;

        if (dst_size == 0 && dst_intr) {
            zdma_dst_done(s);
        }

        /* Write back to buffered descriptor.  */
        s->dsc_dst.words[2] = FIELD_DP32(s->dsc_dst.words[2],
                                         ZDMA_CH_DST_DSCR_WORD2,
                                         SIZE,
                                         dst_size);
    }
}

static void zdma_process_descr(XlnxZDMA *s)
{
    uint64_t src_addr;
    uint32_t src_size, len;
    unsigned int src_cmd;
    bool src_intr, src_type;
    unsigned int ptype = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, POINT_TYPE);
    unsigned int rw_mode = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, MODE);
    unsigned int burst_type = ARRAY_FIELD_EX32(s->regs, ZDMA_CH_DATA_ATTR,
                                               ARBURST);

    src_addr = s->dsc_src.addr;
    src_size = FIELD_EX32(s->dsc_src.words[2], ZDMA_CH_SRC_DSCR_WORD2, SIZE);
    src_cmd = FIELD_EX32(s->dsc_src.words[3], ZDMA_CH_SRC_DSCR_WORD3, CMD);
    src_type = FIELD_EX32(s->dsc_src.words[3], ZDMA_CH_SRC_DSCR_WORD3, TYPE);
    src_intr = FIELD_EX32(s->dsc_src.words[3], ZDMA_CH_SRC_DSCR_WORD3, INTR);

    /* FIXED burst types and non-rw modes are only supported in
     * simple dma mode.
     */
    if (ptype != PT_REG) {
        if (rw_mode != RW_MODE_RW) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "zDMA: rw-mode=%d but not simple DMA mode.\n",
                          rw_mode);
        }
        if (burst_type != AXI_BURST_INCR) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "zDMA: burst_type=%d but not simple DMA mode.\n",
                          burst_type);
        }
        burst_type = AXI_BURST_INCR;
        rw_mode = RW_MODE_RW;
    }

    if (rw_mode == RW_MODE_WO) {
        /* In Simple DMA Write-Only, we need to push DST size bytes
         * regardless of what SRC size is set to.  */
        src_size = FIELD_EX32(s->dsc_dst.words[2], ZDMA_CH_DST_DSCR_WORD2,
                              SIZE);
        memcpy(s->buf, &s->regs[R_ZDMA_CH_WR_ONLY_WORD0], s->cfg.bus_width / 8);
    }

    while (src_size) {
        len = src_size > ARRAY_SIZE(s->buf) ? ARRAY_SIZE(s->buf) : src_size;
        if (burst_type == AXI_BURST_FIXED) {
            if (len > (s->cfg.bus_width / 8)) {
                len = s->cfg.bus_width / 8;
            }
        }

        if (rw_mode == RW_MODE_WO) {
            if (len > s->cfg.bus_width / 8) {
                len = s->cfg.bus_width / 8;
            }
        } else {
            address_space_read(&s->dma_as, src_addr, s->attr, s->buf, len);
            if (burst_type == AXI_BURST_INCR) {
                src_addr += len;
            }
        }

        if (rw_mode != RW_MODE_RO) {
            zdma_write_dst(s, s->buf, len);
        }

        s->regs[R_ZDMA_CH_TOTAL_BYTE] += len;
        src_size -= len;
    }

    ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, DMA_DONE, true);

    if (src_intr) {
        zdma_src_done(s);
    }

    if (ptype == PT_REG || src_cmd == CMD_STOP) {
        ARRAY_FIELD_DP32(s->regs, ZDMA_CH_CTRL2, EN, 0);
        zdma_set_state(s, DISABLED);
    }

    if (src_cmd == CMD_HALT) {
        zdma_set_state(s, PAUSED);
        ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, DMA_PAUSE, 1);
        ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, DMA_DONE, false);
        zdma_ch_imr_update_irq(s);
        return;
    }

    zdma_update_descr_addr(s, src_type, R_ZDMA_CH_SRC_CUR_DSCR_LSB);
}

static void zdma_run(XlnxZDMA *s)
{
    while (s->state == ENABLED && !s->error) {
        zdma_load_src_descriptor(s);

        if (s->error) {
            zdma_set_state(s, DISABLED);
        } else {
            zdma_process_descr(s);
        }
    }

    zdma_ch_imr_update_irq(s);
}

static void zdma_update_descr_addr_from_start(XlnxZDMA *s)
{
    uint64_t src_addr, dst_addr;

    src_addr = zdma_get_regaddr64(s, R_ZDMA_CH_SRC_START_LSB);
    zdma_put_regaddr64(s, R_ZDMA_CH_SRC_CUR_DSCR_LSB, src_addr);
    dst_addr = zdma_get_regaddr64(s, R_ZDMA_CH_DST_START_LSB);
    zdma_put_regaddr64(s, R_ZDMA_CH_DST_CUR_DSCR_LSB, dst_addr);
    zdma_load_dst_descriptor(s);
}

static void zdma_ch_ctrlx_postw(RegisterInfo *reg, uint64_t val64)
{
    XlnxZDMA *s = XLNX_ZDMA(reg->opaque);

    if (ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL2, EN)) {
        s->error = false;

        if (s->state == PAUSED &&
            ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, CONT)) {
            if (ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, CONT_ADDR) == 1) {
                zdma_update_descr_addr_from_start(s);
            } else {
                bool src_type = FIELD_EX32(s->dsc_src.words[3],
                                       ZDMA_CH_SRC_DSCR_WORD3, TYPE);
                zdma_update_descr_addr(s, src_type,
                                          R_ZDMA_CH_SRC_CUR_DSCR_LSB);
            }
            ARRAY_FIELD_DP32(s->regs, ZDMA_CH_CTRL0, CONT, false);
            zdma_set_state(s, ENABLED);
        } else if (s->state == DISABLED) {
            zdma_update_descr_addr_from_start(s);
            zdma_set_state(s, ENABLED);
        }
    } else {
        /* Leave Paused state?  */
        if (s->state == PAUSED &&
            ARRAY_FIELD_EX32(s->regs, ZDMA_CH_CTRL0, CONT)) {
            zdma_set_state(s, DISABLED);
        }
    }

    zdma_run(s);
}

static RegisterAccessInfo zdma_regs_info[] = {
    {   .name = "ZDMA_ERR_CTRL",  .addr = A_ZDMA_ERR_CTRL,
        .rsvd = 0xfffffffe,
    },{ .name = "ZDMA_CH_ISR",  .addr = A_ZDMA_CH_ISR,
        .rsvd = 0xfffff000,
        .w1c = 0xfff,
        .post_write = zdma_ch_isr_postw,
    },{ .name = "ZDMA_CH_IMR",  .addr = A_ZDMA_CH_IMR,
        .reset = 0xfff,
        .rsvd = 0xfffff000,
        .ro = 0xfff,
    },{ .name = "ZDMA_CH_IEN",  .addr = A_ZDMA_CH_IEN,
        .rsvd = 0xfffff000,
        .pre_write = zdma_ch_ien_prew,
    },{ .name = "ZDMA_CH_IDS",  .addr = A_ZDMA_CH_IDS,
        .rsvd = 0xfffff000,
        .pre_write = zdma_ch_ids_prew,
    },{ .name = "ZDMA_CH_CTRL0",  .addr = A_ZDMA_CH_CTRL0,
        .reset = 0x80,
        .rsvd = 0xffffff01,
        .post_write = zdma_ch_ctrlx_postw,
    },{ .name = "ZDMA_CH_CTRL1",  .addr = A_ZDMA_CH_CTRL1,
        .reset = 0x3ff,
        .rsvd = 0xfffffc00,
    },{ .name = "ZDMA_CH_FCI",  .addr = A_ZDMA_CH_FCI,
        .rsvd = 0xffffffc0,
    },{ .name = "ZDMA_CH_STATUS",  .addr = A_ZDMA_CH_STATUS,
        .rsvd = 0xfffffffc,
        .ro = 0x3,
    },{ .name = "ZDMA_CH_DATA_ATTR",  .addr = A_ZDMA_CH_DATA_ATTR,
        .reset = 0x483d20f,
        .rsvd = 0xf0000000,
    },{ .name = "ZDMA_CH_DSCR_ATTR",  .addr = A_ZDMA_CH_DSCR_ATTR,
        .rsvd = 0xfffffe00,
    },{ .name = "ZDMA_CH_SRC_DSCR_WORD0",  .addr = A_ZDMA_CH_SRC_DSCR_WORD0,
    },{ .name = "ZDMA_CH_SRC_DSCR_WORD1",  .addr = A_ZDMA_CH_SRC_DSCR_WORD1,
        .rsvd = 0xfffe0000,
    },{ .name = "ZDMA_CH_SRC_DSCR_WORD2",  .addr = A_ZDMA_CH_SRC_DSCR_WORD2,
        .rsvd = 0xc0000000,
    },{ .name = "ZDMA_CH_SRC_DSCR_WORD3",  .addr = A_ZDMA_CH_SRC_DSCR_WORD3,
        .rsvd = 0xffffffe0,
    },{ .name = "ZDMA_CH_DST_DSCR_WORD0",  .addr = A_ZDMA_CH_DST_DSCR_WORD0,
    },{ .name = "ZDMA_CH_DST_DSCR_WORD1",  .addr = A_ZDMA_CH_DST_DSCR_WORD1,
        .rsvd = 0xfffe0000,
    },{ .name = "ZDMA_CH_DST_DSCR_WORD2",  .addr = A_ZDMA_CH_DST_DSCR_WORD2,
        .rsvd = 0xc0000000,
    },{ .name = "ZDMA_CH_DST_DSCR_WORD3",  .addr = A_ZDMA_CH_DST_DSCR_WORD3,
        .rsvd = 0xfffffffa,
    },{ .name = "ZDMA_CH_WR_ONLY_WORD0",  .addr = A_ZDMA_CH_WR_ONLY_WORD0,
    },{ .name = "ZDMA_CH_WR_ONLY_WORD1",  .addr = A_ZDMA_CH_WR_ONLY_WORD1,
    },{ .name = "ZDMA_CH_WR_ONLY_WORD2",  .addr = A_ZDMA_CH_WR_ONLY_WORD2,
    },{ .name = "ZDMA_CH_WR_ONLY_WORD3",  .addr = A_ZDMA_CH_WR_ONLY_WORD3,
    },{ .name = "ZDMA_CH_SRC_START_LSB",  .addr = A_ZDMA_CH_SRC_START_LSB,
    },{ .name = "ZDMA_CH_SRC_START_MSB",  .addr = A_ZDMA_CH_SRC_START_MSB,
        .rsvd = 0xfffe0000,
    },{ .name = "ZDMA_CH_DST_START_LSB",  .addr = A_ZDMA_CH_DST_START_LSB,
    },{ .name = "ZDMA_CH_DST_START_MSB",  .addr = A_ZDMA_CH_DST_START_MSB,
        .rsvd = 0xfffe0000,
    },{ .name = "ZDMA_CH_SRC_CUR_PYLD_LSB",  .addr = A_ZDMA_CH_SRC_CUR_PYLD_LSB,
        .ro = 0xffffffff,
    },{ .name = "ZDMA_CH_SRC_CUR_PYLD_MSB",  .addr = A_ZDMA_CH_SRC_CUR_PYLD_MSB,
        .rsvd = 0xfffe0000,
        .ro = 0x1ffff,
    },{ .name = "ZDMA_CH_DST_CUR_PYLD_LSB",  .addr = A_ZDMA_CH_DST_CUR_PYLD_LSB,
        .ro = 0xffffffff,
    },{ .name = "ZDMA_CH_DST_CUR_PYLD_MSB",  .addr = A_ZDMA_CH_DST_CUR_PYLD_MSB,
        .rsvd = 0xfffe0000,
        .ro = 0x1ffff,
    },{ .name = "ZDMA_CH_SRC_CUR_DSCR_LSB",  .addr = A_ZDMA_CH_SRC_CUR_DSCR_LSB,
        .ro = 0xffffffff,
    },{ .name = "ZDMA_CH_SRC_CUR_DSCR_MSB",  .addr = A_ZDMA_CH_SRC_CUR_DSCR_MSB,
        .rsvd = 0xfffe0000,
        .ro = 0x1ffff,
    },{ .name = "ZDMA_CH_DST_CUR_DSCR_LSB",  .addr = A_ZDMA_CH_DST_CUR_DSCR_LSB,
        .ro = 0xffffffff,
    },{ .name = "ZDMA_CH_DST_CUR_DSCR_MSB",  .addr = A_ZDMA_CH_DST_CUR_DSCR_MSB,
        .rsvd = 0xfffe0000,
        .ro = 0x1ffff,
    },{ .name = "ZDMA_CH_TOTAL_BYTE",  .addr = A_ZDMA_CH_TOTAL_BYTE,
        .w1c = 0xffffffff,
    },{ .name = "ZDMA_CH_RATE_CNTL",  .addr = A_ZDMA_CH_RATE_CNTL,
        .rsvd = 0xfffff000,
    },{ .name = "ZDMA_CH_IRQ_SRC_ACCT",  .addr = A_ZDMA_CH_IRQ_SRC_ACCT,
        .rsvd = 0xffffff00,
        .ro = 0xff,
        .cor = 0xff,
    },{ .name = "ZDMA_CH_IRQ_DST_ACCT",  .addr = A_ZDMA_CH_IRQ_DST_ACCT,
        .rsvd = 0xffffff00,
        .ro = 0xff,
        .cor = 0xff,
    },{ .name = "ZDMA_CH_DBG0",  .addr = A_ZDMA_CH_DBG0,
        .rsvd = 0xfffffe00,
        .ro = 0x1ff,

        /*
         * There's SW out there that will check the debug regs for free space.
         * Claim that we always have 0x100 free.
         */
        .reset = 0x100
    },{ .name = "ZDMA_CH_DBG1",  .addr = A_ZDMA_CH_DBG1,
        .rsvd = 0xfffffe00,
        .ro = 0x1ff,
    },{ .name = "ZDMA_CH_CTRL2",  .addr = A_ZDMA_CH_CTRL2,
        .rsvd = 0xfffffffe,
        .post_write = zdma_ch_ctrlx_postw,
    }
};

static void zdma_reset(DeviceState *dev)
{
    XlnxZDMA *s = XLNX_ZDMA(dev);
    unsigned int i;

    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
        register_reset(&s->regs_info[i]);
    }

    zdma_ch_imr_update_irq(s);
}

static uint64_t zdma_read(void *opaque, hwaddr addr, unsigned size)
{
    XlnxZDMA *s = XLNX_ZDMA(opaque);
    RegisterInfo *r = &s->regs_info[addr / 4];

    if (!r->data) {
        char *path = object_get_canonical_path(OBJECT(s));
        qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
                 path,
                 addr);
        g_free(path);
        ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
        zdma_ch_imr_update_irq(s);
        return 0;
    }
    return register_read(r, ~0, NULL, false);
}

static void zdma_write(void *opaque, hwaddr addr, uint64_t value,
                      unsigned size)
{
    XlnxZDMA *s = XLNX_ZDMA(opaque);
    RegisterInfo *r = &s->regs_info[addr / 4];

    if (!r->data) {
        char *path = object_get_canonical_path(OBJECT(s));
        qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
                 path,
                 addr, value);
        g_free(path);
        ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
        zdma_ch_imr_update_irq(s);
        return;
    }
    register_write(r, value, ~0, NULL, false);
}

static const MemoryRegionOps zdma_ops = {
    .read = zdma_read,
    .write = zdma_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static void zdma_realize(DeviceState *dev, Error **errp)
{
    XlnxZDMA *s = XLNX_ZDMA(dev);
    unsigned int i;

    if (!s->dma_mr) {
        error_setg(errp, TYPE_XLNX_ZDMA " 'dma' link not set");
        return;
    }
    address_space_init(&s->dma_as, s->dma_mr, "zdma-dma");

    for (i = 0; i < ARRAY_SIZE(zdma_regs_info); ++i) {
        RegisterInfo *r = &s->regs_info[zdma_regs_info[i].addr / 4];

        *r = (RegisterInfo) {
            .data = (uint8_t *)&s->regs[
                    zdma_regs_info[i].addr / 4],
            .data_size = sizeof(uint32_t),
            .access = &zdma_regs_info[i],
            .opaque = s,
        };
    }

    s->attr = MEMTXATTRS_UNSPECIFIED;
}

static void zdma_init(Object *obj)
{
    XlnxZDMA *s = XLNX_ZDMA(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    memory_region_init_io(&s->iomem, obj, &zdma_ops, s,
                          TYPE_XLNX_ZDMA, ZDMA_R_MAX * 4);
    sysbus_init_mmio(sbd, &s->iomem);
    sysbus_init_irq(sbd, &s->irq_zdma_ch_imr);
}

static const VMStateDescription vmstate_zdma = {
    .name = TYPE_XLNX_ZDMA,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, XlnxZDMA, ZDMA_R_MAX),
        VMSTATE_UINT32(state, XlnxZDMA),
        VMSTATE_UINT32_ARRAY(dsc_src.words, XlnxZDMA, 4),
        VMSTATE_UINT32_ARRAY(dsc_dst.words, XlnxZDMA, 4),
        VMSTATE_END_OF_LIST(),
    }
};

static Property zdma_props[] = {
    DEFINE_PROP_UINT32("bus-width", XlnxZDMA, cfg.bus_width, 64),
    DEFINE_PROP_LINK("dma", XlnxZDMA, dma_mr,
                     TYPE_MEMORY_REGION, MemoryRegion *),
    DEFINE_PROP_END_OF_LIST(),
};

static void zdma_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    device_class_set_legacy_reset(dc, zdma_reset);
    dc->realize = zdma_realize;
    device_class_set_props(dc, zdma_props);
    dc->vmsd = &vmstate_zdma;
}

static const TypeInfo zdma_info = {
    .name          = TYPE_XLNX_ZDMA,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(XlnxZDMA),
    .class_init    = zdma_class_init,
    .instance_init = zdma_init,
};

static void zdma_register_types(void)
{
    type_register_static(&zdma_info);
}

type_init(zdma_register_types)
