/*
 * QEMU AHCI Emulation
 *
 * Copyright (c) 2010 qiaochong@loongson.cn
 * Copyright (c) 2010 Roland Elek <elek.roland@gmail.com>
 * Copyright (c) 2010 Sebastian Herbszt <herbszt@gmx.de>
 * Copyright (c) 2010 Alexander Graf <agraf@suse.de>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "hw/irq.h"
#include "migration/vmstate.h"

#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "system/block-backend.h"
#include "system/dma.h"
#include "ahci-internal.h"
#include "ide-internal.h"

#include "trace.h"

static void check_cmd(AHCIState *s, int port);
static void handle_cmd(AHCIState *s, int port, uint8_t slot);
static void ahci_reset_port(AHCIState *s, int port);
static bool ahci_write_fis_d2h(AHCIDevice *ad, bool d2h_fis_i);
static void ahci_clear_cmd_issue(AHCIDevice *ad, uint8_t slot);
static void ahci_init_d2h(AHCIDevice *ad);
static int ahci_dma_prepare_buf(const IDEDMA *dma, int32_t limit);
static bool ahci_map_clb_address(AHCIDevice *ad);
static bool ahci_map_fis_address(AHCIDevice *ad);
static void ahci_unmap_clb_address(AHCIDevice *ad);
static void ahci_unmap_fis_address(AHCIDevice *ad);

static const char *AHCIHostReg_lookup[AHCI_HOST_REG__COUNT] = {
    [AHCI_HOST_REG_CAP]        = "CAP",
    [AHCI_HOST_REG_CTL]        = "GHC",
    [AHCI_HOST_REG_IRQ_STAT]   = "IS",
    [AHCI_HOST_REG_PORTS_IMPL] = "PI",
    [AHCI_HOST_REG_VERSION]    = "VS",
    [AHCI_HOST_REG_CCC_CTL]    = "CCC_CTL",
    [AHCI_HOST_REG_CCC_PORTS]  = "CCC_PORTS",
    [AHCI_HOST_REG_EM_LOC]     = "EM_LOC",
    [AHCI_HOST_REG_EM_CTL]     = "EM_CTL",
    [AHCI_HOST_REG_CAP2]       = "CAP2",
    [AHCI_HOST_REG_BOHC]       = "BOHC",
};

static const char *AHCIPortReg_lookup[AHCI_PORT_REG__COUNT] = {
    [AHCI_PORT_REG_LST_ADDR]    = "PxCLB",
    [AHCI_PORT_REG_LST_ADDR_HI] = "PxCLBU",
    [AHCI_PORT_REG_FIS_ADDR]    = "PxFB",
    [AHCI_PORT_REG_FIS_ADDR_HI] = "PxFBU",
    [AHCI_PORT_REG_IRQ_STAT]    = "PxIS",
    [AHCI_PORT_REG_IRQ_MASK]    = "PXIE",
    [AHCI_PORT_REG_CMD]         = "PxCMD",
    [7]                         = "Reserved",
    [AHCI_PORT_REG_TFDATA]      = "PxTFD",
    [AHCI_PORT_REG_SIG]         = "PxSIG",
    [AHCI_PORT_REG_SCR_STAT]    = "PxSSTS",
    [AHCI_PORT_REG_SCR_CTL]     = "PxSCTL",
    [AHCI_PORT_REG_SCR_ERR]     = "PxSERR",
    [AHCI_PORT_REG_SCR_ACT]     = "PxSACT",
    [AHCI_PORT_REG_CMD_ISSUE]   = "PxCI",
    [AHCI_PORT_REG_SCR_NOTIF]   = "PxSNTF",
    [AHCI_PORT_REG_FIS_CTL]     = "PxFBS",
    [AHCI_PORT_REG_DEV_SLEEP]   = "PxDEVSLP",
    [18 ... 27]                 = "Reserved",
    [AHCI_PORT_REG_VENDOR_1 ...
     AHCI_PORT_REG_VENDOR_4]    = "PxVS",
};

static const char *AHCIPortIRQ_lookup[AHCI_PORT_IRQ__COUNT] = {
    [AHCI_PORT_IRQ_BIT_DHRS] = "DHRS",
    [AHCI_PORT_IRQ_BIT_PSS]  = "PSS",
    [AHCI_PORT_IRQ_BIT_DSS]  = "DSS",
    [AHCI_PORT_IRQ_BIT_SDBS] = "SDBS",
    [AHCI_PORT_IRQ_BIT_UFS]  = "UFS",
    [AHCI_PORT_IRQ_BIT_DPS]  = "DPS",
    [AHCI_PORT_IRQ_BIT_PCS]  = "PCS",
    [AHCI_PORT_IRQ_BIT_DMPS] = "DMPS",
    [8 ... 21]               = "RESERVED",
    [AHCI_PORT_IRQ_BIT_PRCS] = "PRCS",
    [AHCI_PORT_IRQ_BIT_IPMS] = "IPMS",
    [AHCI_PORT_IRQ_BIT_OFS]  = "OFS",
    [25]                     = "RESERVED",
    [AHCI_PORT_IRQ_BIT_INFS] = "INFS",
    [AHCI_PORT_IRQ_BIT_IFS]  = "IFS",
    [AHCI_PORT_IRQ_BIT_HBDS] = "HBDS",
    [AHCI_PORT_IRQ_BIT_HBFS] = "HBFS",
    [AHCI_PORT_IRQ_BIT_TFES] = "TFES",
    [AHCI_PORT_IRQ_BIT_CPDS] = "CPDS"
};

static uint32_t ahci_port_read(AHCIState *s, int port, int offset)
{
    uint32_t val;
    AHCIPortRegs *pr = &s->dev[port].port_regs;
    enum AHCIPortReg regnum = offset / sizeof(uint32_t);
    assert(regnum < (AHCI_PORT_ADDR_OFFSET_LEN / sizeof(uint32_t)));

    switch (regnum) {
    case AHCI_PORT_REG_LST_ADDR:
        val = pr->lst_addr;
        break;
    case AHCI_PORT_REG_LST_ADDR_HI:
        val = pr->lst_addr_hi;
        break;
    case AHCI_PORT_REG_FIS_ADDR:
        val = pr->fis_addr;
        break;
    case AHCI_PORT_REG_FIS_ADDR_HI:
        val = pr->fis_addr_hi;
        break;
    case AHCI_PORT_REG_IRQ_STAT:
        val = pr->irq_stat;
        break;
    case AHCI_PORT_REG_IRQ_MASK:
        val = pr->irq_mask;
        break;
    case AHCI_PORT_REG_CMD:
        val = pr->cmd;
        break;
    case AHCI_PORT_REG_TFDATA:
        val = pr->tfdata;
        break;
    case AHCI_PORT_REG_SIG:
        val = pr->sig;
        break;
    case AHCI_PORT_REG_SCR_STAT:
        if (s->dev[port].port.ifs[0].blk) {
            val = SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP |
                  SATA_SCR_SSTATUS_SPD_GEN1 | SATA_SCR_SSTATUS_IPM_ACTIVE;
        } else {
            val = SATA_SCR_SSTATUS_DET_NODEV;
        }
        break;
    case AHCI_PORT_REG_SCR_CTL:
        val = pr->scr_ctl;
        break;
    case AHCI_PORT_REG_SCR_ERR:
        val = pr->scr_err;
        break;
    case AHCI_PORT_REG_SCR_ACT:
        val = pr->scr_act;
        break;
    case AHCI_PORT_REG_CMD_ISSUE:
        val = pr->cmd_issue;
        break;
    default:
        trace_ahci_port_read_default(s, port, AHCIPortReg_lookup[regnum],
                                     offset);
        val = 0;
    }

    trace_ahci_port_read(s, port, AHCIPortReg_lookup[regnum], offset, val);
    return val;
}

static void ahci_check_irq(AHCIState *s)
{
    int i;
    uint32_t old_irq = s->control_regs.irqstatus;

    s->control_regs.irqstatus = 0;
    for (i = 0; i < s->ports; i++) {
        AHCIPortRegs *pr = &s->dev[i].port_regs;
        if (pr->irq_stat & pr->irq_mask) {
            s->control_regs.irqstatus |= (1 << i);
        }
    }
    trace_ahci_check_irq(s, old_irq, s->control_regs.irqstatus);
    if (s->control_regs.irqstatus &&
        (s->control_regs.ghc & HOST_CTL_IRQ_EN)) {
        trace_ahci_irq_raise(s);
        qemu_irq_raise(s->irq);
    } else {
        trace_ahci_irq_lower(s);
        qemu_irq_lower(s->irq);
    }
}

static void ahci_trigger_irq(AHCIState *s, AHCIDevice *d,
                             enum AHCIPortIRQ irqbit)
{
    g_assert((unsigned)irqbit < 32);
    uint32_t irq = 1U << irqbit;
    uint32_t irqstat = d->port_regs.irq_stat | irq;

    trace_ahci_trigger_irq(s, d->port_no,
                           AHCIPortIRQ_lookup[irqbit], irq,
                           d->port_regs.irq_stat, irqstat,
                           irqstat & d->port_regs.irq_mask);

    d->port_regs.irq_stat = irqstat;
    ahci_check_irq(s);
}

static void map_page(AddressSpace *as, uint8_t **ptr, uint64_t addr,
                     uint32_t wanted)
{
    hwaddr len = wanted;

    if (*ptr) {
        dma_memory_unmap(as, *ptr, len, DMA_DIRECTION_FROM_DEVICE, len);
    }

    *ptr = dma_memory_map(as, addr, &len, DMA_DIRECTION_FROM_DEVICE,
                          MEMTXATTRS_UNSPECIFIED);
    if (len < wanted && *ptr) {
        dma_memory_unmap(as, *ptr, len, DMA_DIRECTION_FROM_DEVICE, len);
        *ptr = NULL;
    }
}

/**
 * Check the cmd register to see if we should start or stop
 * the DMA or FIS RX engines.
 *
 * @ad: Device to dis/engage.
 *
 * @return 0 on success, -1 on error.
 */
static int ahci_cond_start_engines(AHCIDevice *ad)
{
    AHCIPortRegs *pr = &ad->port_regs;
    bool cmd_start = pr->cmd & PORT_CMD_START;
    bool cmd_on    = pr->cmd & PORT_CMD_LIST_ON;
    bool fis_start = pr->cmd & PORT_CMD_FIS_RX;
    bool fis_on    = pr->cmd & PORT_CMD_FIS_ON;

    if (cmd_start && !cmd_on) {
        if (!ahci_map_clb_address(ad)) {
            pr->cmd &= ~PORT_CMD_START;
            error_report("AHCI: Failed to start DMA engine: "
                         "bad command list buffer address");
            return -1;
        }
    } else if (!cmd_start && cmd_on) {
        ahci_unmap_clb_address(ad);
    }

    if (fis_start && !fis_on) {
        if (!ahci_map_fis_address(ad)) {
            pr->cmd &= ~PORT_CMD_FIS_RX;
            error_report("AHCI: Failed to start FIS receive engine: "
                         "bad FIS receive buffer address");
            return -1;
        }
    } else if (!fis_start && fis_on) {
        ahci_unmap_fis_address(ad);
    }

    return 0;
}

static void ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
{
    AHCIPortRegs *pr = &s->dev[port].port_regs;
    enum AHCIPortReg regnum = offset / sizeof(uint32_t);
    assert(regnum < (AHCI_PORT_ADDR_OFFSET_LEN / sizeof(uint32_t)));
    trace_ahci_port_write(s, port, AHCIPortReg_lookup[regnum], offset, val);

    switch (regnum) {
    case AHCI_PORT_REG_LST_ADDR:
        pr->lst_addr = val;
        break;
    case AHCI_PORT_REG_LST_ADDR_HI:
        pr->lst_addr_hi = val;
        break;
    case AHCI_PORT_REG_FIS_ADDR:
        pr->fis_addr = val;
        break;
    case AHCI_PORT_REG_FIS_ADDR_HI:
        pr->fis_addr_hi = val;
        break;
    case AHCI_PORT_REG_IRQ_STAT:
        pr->irq_stat &= ~val;
        ahci_check_irq(s);
        break;
    case AHCI_PORT_REG_IRQ_MASK:
        pr->irq_mask = val & 0xfdc000ff;
        ahci_check_irq(s);
        break;
    case AHCI_PORT_REG_CMD:
        if ((pr->cmd & PORT_CMD_START) && !(val & PORT_CMD_START)) {
            pr->scr_act = 0;
            pr->cmd_issue = 0;
        }

        /* Block any Read-only fields from being set;
         * including LIST_ON and FIS_ON.
         * The spec requires to set ICC bits to zero after the ICC change
         * is done. We don't support ICC state changes, therefore always
         * force the ICC bits to zero.
         */
        pr->cmd = (pr->cmd & PORT_CMD_RO_MASK) |
            (val & ~(PORT_CMD_RO_MASK | PORT_CMD_ICC_MASK));

        /* Check FIS RX and CLB engines */
        ahci_cond_start_engines(&s->dev[port]);

        /* XXX usually the FIS would be pending on the bus here and
           issuing deferred until the OS enables FIS receival.
           Instead, we only submit it once - which works in most
           cases, but is a hack. */
        if ((pr->cmd & PORT_CMD_FIS_ON) &&
            !s->dev[port].init_d2h_sent) {
            ahci_init_d2h(&s->dev[port]);
        }

        check_cmd(s, port);
        break;
    case AHCI_PORT_REG_TFDATA:
    case AHCI_PORT_REG_SIG:
    case AHCI_PORT_REG_SCR_STAT:
        /* Read Only */
        break;
    case AHCI_PORT_REG_SCR_CTL:
        if (((pr->scr_ctl & AHCI_SCR_SCTL_DET) == 1) &&
            ((val & AHCI_SCR_SCTL_DET) == 0)) {
            ahci_reset_port(s, port);
        }
        pr->scr_ctl = val;
        break;
    case AHCI_PORT_REG_SCR_ERR:
        pr->scr_err &= ~val;
        break;
    case AHCI_PORT_REG_SCR_ACT:
        /* RW1 */
        pr->scr_act |= val;
        break;
    case AHCI_PORT_REG_CMD_ISSUE:
        pr->cmd_issue |= val;
        check_cmd(s, port);
        break;
    default:
        trace_ahci_port_write_unimpl(s, port, AHCIPortReg_lookup[regnum],
                                     offset, val);
        qemu_log_mask(LOG_UNIMP, "Attempted write to unimplemented register: "
                      "AHCI port %d register %s, offset 0x%x: 0x%"PRIx32,
                      port, AHCIPortReg_lookup[regnum], offset, val);
        break;
    }
}

static uint64_t ahci_mem_read_32(void *opaque, hwaddr addr)
{
    AHCIState *s = opaque;
    uint32_t val = 0;

    if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
        enum AHCIHostReg regnum = addr / 4;
        assert(regnum < AHCI_HOST_REG__COUNT);

        switch (regnum) {
        case AHCI_HOST_REG_CAP:
            val = s->control_regs.cap;
            break;
        case AHCI_HOST_REG_CTL:
            val = s->control_regs.ghc;
            break;
        case AHCI_HOST_REG_IRQ_STAT:
            val = s->control_regs.irqstatus;
            break;
        case AHCI_HOST_REG_PORTS_IMPL:
            val = s->control_regs.impl;
            break;
        case AHCI_HOST_REG_VERSION:
            val = s->control_regs.version;
            break;
        default:
            trace_ahci_mem_read_32_host_default(s, AHCIHostReg_lookup[regnum],
                                                addr);
        }
        trace_ahci_mem_read_32_host(s, AHCIHostReg_lookup[regnum], addr, val);
    } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
               (addr < (AHCI_PORT_REGS_START_ADDR +
                (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) {
        val = ahci_port_read(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7,
                             addr & AHCI_PORT_ADDR_OFFSET_MASK);
    } else {
        trace_ahci_mem_read_32_default(s, addr, val);
    }

    trace_ahci_mem_read_32(s, addr, val);
    return val;
}


/**
 * AHCI 1.3 section 3 ("HBA Memory Registers")
 * Support unaligned 8/16/32 bit reads, and 64 bit aligned reads.
 * Caller is responsible for masking unwanted higher order bytes.
 */
static uint64_t ahci_mem_read(void *opaque, hwaddr addr, unsigned size)
{
    hwaddr aligned = addr & ~0x3;
    int ofst = addr - aligned;
    uint64_t lo = ahci_mem_read_32(opaque, aligned);
    uint64_t hi;
    uint64_t val;

    /* if < 8 byte read does not cross 4 byte boundary */
    if (ofst + size <= 4) {
        val = lo >> (ofst * 8);
    } else {
        g_assert(size > 1);

        /* If the 64bit read is unaligned, we will produce undefined
         * results. AHCI does not support unaligned 64bit reads. */
        hi = ahci_mem_read_32(opaque, aligned + 4);
        val = (hi << 32 | lo) >> (ofst * 8);
    }

    trace_ahci_mem_read(opaque, size, addr, val);
    return val;
}


static void ahci_mem_write(void *opaque, hwaddr addr,
                           uint64_t val, unsigned size)
{
    AHCIState *s = opaque;

    trace_ahci_mem_write(s, size, addr, val);

    /* Only aligned reads are allowed on AHCI */
    if (addr & 3) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "ahci: Mis-aligned write to addr 0x%03" HWADDR_PRIX "\n",
                      addr);
        return;
    }

    if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
        enum AHCIHostReg regnum = addr / 4;
        assert(regnum < AHCI_HOST_REG__COUNT);

        switch (regnum) {
        case AHCI_HOST_REG_CAP: /* R/WO, RO */
            /* FIXME handle R/WO */
            break;
        case AHCI_HOST_REG_CTL: /* R/W */
            if (val & HOST_CTL_RESET) {
                ahci_reset(s);
            } else {
                s->control_regs.ghc = (val & 0x3) | HOST_CTL_AHCI_EN;
                ahci_check_irq(s);
            }
            break;
        case AHCI_HOST_REG_IRQ_STAT: /* R/WC, RO */
            s->control_regs.irqstatus &= ~val;
            ahci_check_irq(s);
            break;
        case AHCI_HOST_REG_PORTS_IMPL: /* R/WO, RO */
            /* FIXME handle R/WO */
            break;
        case AHCI_HOST_REG_VERSION: /* RO */
            /* FIXME report write? */
            break;
        default:
            qemu_log_mask(LOG_UNIMP,
                          "Attempted write to unimplemented register: "
                          "AHCI host register %s, "
                          "offset 0x%"PRIx64": 0x%"PRIx64,
                          AHCIHostReg_lookup[regnum], addr, val);
            trace_ahci_mem_write_host_unimpl(s, size,
                                             AHCIHostReg_lookup[regnum], addr);
        }
        trace_ahci_mem_write_host(s, size, AHCIHostReg_lookup[regnum],
                                     addr, val);
    } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
               (addr < (AHCI_PORT_REGS_START_ADDR +
                        (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) {
        ahci_port_write(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7,
                        addr & AHCI_PORT_ADDR_OFFSET_MASK, val);
    } else {
        qemu_log_mask(LOG_UNIMP, "Attempted write to unimplemented register: "
                      "AHCI global register at offset 0x%"PRIx64": 0x%"PRIx64,
                      addr, val);
        trace_ahci_mem_write_unimpl(s, size, addr, val);
    }
}

static const MemoryRegionOps ahci_mem_ops = {
    .read = ahci_mem_read,
    .write = ahci_mem_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static uint64_t ahci_idp_read(void *opaque, hwaddr addr,
                              unsigned size)
{
    AHCIState *s = opaque;

    if (addr == s->idp_offset) {
        /* index register */
        return s->idp_index;
    } else if (addr == s->idp_offset + 4) {
        /* data register - do memory read at location selected by index */
        return ahci_mem_read(opaque, s->idp_index, size);
    } else {
        return 0;
    }
}

static void ahci_idp_write(void *opaque, hwaddr addr,
                           uint64_t val, unsigned size)
{
    AHCIState *s = opaque;

    if (addr == s->idp_offset) {
        /* index register - mask off reserved bits */
        s->idp_index = (uint32_t)val & ((AHCI_MEM_BAR_SIZE - 1) & ~3);
    } else if (addr == s->idp_offset + 4) {
        /* data register - do memory write at location selected by index */
        ahci_mem_write(opaque, s->idp_index, val, size);
    }
}

static const MemoryRegionOps ahci_idp_ops = {
    .read = ahci_idp_read,
    .write = ahci_idp_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};


static void ahci_reg_init(AHCIState *s)
{
    int i;

    s->control_regs.cap = (s->ports - 1) |
                          (AHCI_NUM_COMMAND_SLOTS << 8) |
                          (AHCI_SUPPORTED_SPEED_GEN1 << AHCI_SUPPORTED_SPEED) |
                          HOST_CAP_NCQ | HOST_CAP_AHCI | HOST_CAP_64;

    s->control_regs.impl = (1 << s->ports) - 1;

    s->control_regs.version = AHCI_VERSION_1_0;

    for (i = 0; i < s->ports; i++) {
        s->dev[i].port_state = STATE_RUN;
    }
}

static void check_cmd(AHCIState *s, int port)
{
    AHCIPortRegs *pr = &s->dev[port].port_regs;
    uint8_t slot;

    if ((pr->cmd & PORT_CMD_START) && pr->cmd_issue) {
        for (slot = 0; (slot < 32) && pr->cmd_issue; slot++) {
            if (pr->cmd_issue & (1U << slot)) {
                handle_cmd(s, port, slot);
            }
        }
    }
}

static void ahci_check_cmd_bh(void *opaque)
{
    AHCIDevice *ad = opaque;

    qemu_bh_delete(ad->check_bh);
    ad->check_bh = NULL;

    check_cmd(ad->hba, ad->port_no);
}

static void ahci_init_d2h(AHCIDevice *ad)
{
    IDEState *ide_state = &ad->port.ifs[0];
    AHCIPortRegs *pr = &ad->port_regs;

    if (ad->init_d2h_sent) {
        return;
    }

    /*
     * For simplicity, do not call ahci_clear_cmd_issue() for this
     * ahci_write_fis_d2h(). (The reset value for PxCI is 0.)
     */
    if (ahci_write_fis_d2h(ad, true)) {
        ad->init_d2h_sent = true;
        /* We're emulating receiving the first Reg D2H FIS from the device;
         * Update the SIG register, but otherwise proceed as normal. */
        pr->sig = ((uint32_t)ide_state->hcyl << 24) |
            (ide_state->lcyl << 16) |
            (ide_state->sector << 8) |
            (ide_state->nsector & 0xFF);
    }
}

static void ahci_set_signature(AHCIDevice *ad, uint32_t sig)
{
    IDEState *s = &ad->port.ifs[0];
    s->hcyl = sig >> 24 & 0xFF;
    s->lcyl = sig >> 16 & 0xFF;
    s->sector = sig >> 8 & 0xFF;
    s->nsector = sig & 0xFF;

    trace_ahci_set_signature(ad->hba, ad->port_no, s->nsector, s->sector,
                             s->lcyl, s->hcyl, sig);
}

static void ahci_reset_port(AHCIState *s, int port)
{
    AHCIDevice *d = &s->dev[port];
    AHCIPortRegs *pr = &d->port_regs;
    IDEState *ide_state = &d->port.ifs[0];
    int i;

    trace_ahci_reset_port(s, port);

    ide_bus_reset(&d->port);
    ide_state->ncq_queues = AHCI_MAX_CMDS;

    pr->scr_stat = 0;
    pr->scr_err = 0;
    pr->scr_act = 0;
    pr->tfdata = 0x7F;
    pr->sig = 0xFFFFFFFF;
    pr->cmd_issue = 0;
    d->busy_slot = -1;
    d->init_d2h_sent = false;

    ide_state = &s->dev[port].port.ifs[0];
    if (!ide_state->blk) {
        return;
    }

    /* reset ncq queue */
    for (i = 0; i < AHCI_MAX_CMDS; i++) {
        NCQTransferState *ncq_tfs = &s->dev[port].ncq_tfs[i];
        ncq_tfs->halt = false;
        if (!ncq_tfs->used) {
            continue;
        }

        if (ncq_tfs->aiocb) {
            blk_aio_cancel(ncq_tfs->aiocb);
            ncq_tfs->aiocb = NULL;
        }

        /* Maybe we just finished the request thanks to blk_aio_cancel() */
        if (!ncq_tfs->used) {
            continue;
        }

        qemu_sglist_destroy(&ncq_tfs->sglist);
        ncq_tfs->used = 0;
    }

    s->dev[port].port_state = STATE_RUN;
    if (ide_state->drive_kind == IDE_CD) {
        ahci_set_signature(d, SATA_SIGNATURE_CDROM);
        ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT;
    } else {
        ahci_set_signature(d, SATA_SIGNATURE_DISK);
        ide_state->status = SEEK_STAT | WRERR_STAT;
    }

    ide_state->error = 1;
    ahci_init_d2h(d);
}

/* Buffer pretty output based on a raw FIS structure. */
static char *ahci_pretty_buffer_fis(const uint8_t *fis, int cmd_len)
{
    int i;
    GString *s = g_string_new("FIS:");

    for (i = 0; i < cmd_len; i++) {
        if ((i & 0xf) == 0) {
            g_string_append_printf(s, "\n0x%02x: ", i);
        }
        g_string_append_printf(s, "%02x ", fis[i]);
    }
    g_string_append_c(s, '\n');

    return g_string_free(s, FALSE);
}

static bool ahci_map_fis_address(AHCIDevice *ad)
{
    AHCIPortRegs *pr = &ad->port_regs;
    map_page(ad->hba->as, &ad->res_fis,
             ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256);
    if (ad->res_fis != NULL) {
        pr->cmd |= PORT_CMD_FIS_ON;
        return true;
    }

    pr->cmd &= ~PORT_CMD_FIS_ON;
    return false;
}

static void ahci_unmap_fis_address(AHCIDevice *ad)
{
    if (ad->res_fis == NULL) {
        trace_ahci_unmap_fis_address_null(ad->hba, ad->port_no);
        return;
    }
    ad->port_regs.cmd &= ~PORT_CMD_FIS_ON;
    dma_memory_unmap(ad->hba->as, ad->res_fis, 256,
                     DMA_DIRECTION_FROM_DEVICE, 256);
    ad->res_fis = NULL;
}

static bool ahci_map_clb_address(AHCIDevice *ad)
{
    AHCIPortRegs *pr = &ad->port_regs;
    ad->cur_cmd = NULL;
    map_page(ad->hba->as, &ad->lst,
             ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024);
    if (ad->lst != NULL) {
        pr->cmd |= PORT_CMD_LIST_ON;
        return true;
    }

    pr->cmd &= ~PORT_CMD_LIST_ON;
    return false;
}

static void ahci_unmap_clb_address(AHCIDevice *ad)
{
    if (ad->lst == NULL) {
        trace_ahci_unmap_clb_address_null(ad->hba, ad->port_no);
        return;
    }
    ad->port_regs.cmd &= ~PORT_CMD_LIST_ON;
    dma_memory_unmap(ad->hba->as, ad->lst, 1024,
                     DMA_DIRECTION_FROM_DEVICE, 1024);
    ad->lst = NULL;
}

static void ahci_write_fis_sdb(AHCIState *s, NCQTransferState *ncq_tfs)
{
    AHCIDevice *ad = ncq_tfs->drive;
    AHCIPortRegs *pr = &ad->port_regs;
    IDEState *ide_state;
    SDBFIS *sdb_fis;

    if (!ad->res_fis ||
        !(pr->cmd & PORT_CMD_FIS_RX)) {
        return;
    }

    sdb_fis = (SDBFIS *)&ad->res_fis[RES_FIS_SDBFIS];
    ide_state = &ad->port.ifs[0];

    sdb_fis->type = SATA_FIS_TYPE_SDB;
    /* Interrupt pending & Notification bit */
    sdb_fis->flags = 0x40; /* Interrupt bit, always 1 for NCQ */
    sdb_fis->status = ide_state->status & 0x77;
    sdb_fis->error = ide_state->error;
    /* update SAct field in SDB_FIS */
    sdb_fis->payload = cpu_to_le32(ad->finished);

    /* Update shadow registers (except BSY 0x80 and DRQ 0x08) */
    pr->tfdata = (ad->port.ifs[0].error << 8) |
        (ad->port.ifs[0].status & 0x77) |
        (pr->tfdata & 0x88);
    pr->scr_act &= ~ad->finished;
    ad->finished = 0;

    /*
     * TFES IRQ is always raised if ERR_STAT is set, regardless of I bit.
     * If ERR_STAT is not set, trigger SDBS IRQ if interrupt bit is set
     * (which currently, it always is).
     */
    if (sdb_fis->status & ERR_STAT) {
        ahci_trigger_irq(s, ad, AHCI_PORT_IRQ_BIT_TFES);
    } else if (sdb_fis->flags & 0x40) {
        ahci_trigger_irq(s, ad, AHCI_PORT_IRQ_BIT_SDBS);
    }
}

static void ahci_write_fis_pio(AHCIDevice *ad, uint16_t len, bool pio_fis_i)
{
    AHCIPortRegs *pr = &ad->port_regs;
    uint8_t *pio_fis;
    IDEState *s = &ad->port.ifs[0];

    if (!ad->res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) {
        return;
    }

    pio_fis = &ad->res_fis[RES_FIS_PSFIS];

    pio_fis[0] = SATA_FIS_TYPE_PIO_SETUP;
    pio_fis[1] = (pio_fis_i ? (1 << 6) : 0);
    pio_fis[2] = s->status;
    pio_fis[3] = s->error;

    pio_fis[4] = s->sector;
    pio_fis[5] = s->lcyl;
    pio_fis[6] = s->hcyl;
    pio_fis[7] = s->select;
    pio_fis[8] = s->hob_sector;
    pio_fis[9] = s->hob_lcyl;
    pio_fis[10] = s->hob_hcyl;
    pio_fis[11] = 0;
    pio_fis[12] = s->nsector & 0xFF;
    pio_fis[13] = (s->nsector >> 8) & 0xFF;
    pio_fis[14] = 0;
    pio_fis[15] = s->status;
    pio_fis[16] = len & 255;
    pio_fis[17] = len >> 8;
    pio_fis[18] = 0;
    pio_fis[19] = 0;

    /* Update shadow registers: */
    pr->tfdata = (ad->port.ifs[0].error << 8) |
        ad->port.ifs[0].status;

    if (pio_fis[2] & ERR_STAT) {
        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES);
    }
}

static bool ahci_write_fis_d2h(AHCIDevice *ad, bool d2h_fis_i)
{
    AHCIPortRegs *pr = &ad->port_regs;
    uint8_t *d2h_fis;
    int i;
    IDEState *s = &ad->port.ifs[0];

    if (!ad->res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) {
        return false;
    }

    d2h_fis = &ad->res_fis[RES_FIS_RFIS];

    d2h_fis[0] = SATA_FIS_TYPE_REGISTER_D2H;
    d2h_fis[1] = d2h_fis_i ? (1 << 6) : 0; /* interrupt bit */
    d2h_fis[2] = s->status;
    d2h_fis[3] = s->error;

    d2h_fis[4] = s->sector;
    d2h_fis[5] = s->lcyl;
    d2h_fis[6] = s->hcyl;
    d2h_fis[7] = s->select;
    d2h_fis[8] = s->hob_sector;
    d2h_fis[9] = s->hob_lcyl;
    d2h_fis[10] = s->hob_hcyl;
    d2h_fis[11] = 0;
    d2h_fis[12] = s->nsector & 0xFF;
    d2h_fis[13] = (s->nsector >> 8) & 0xFF;
    for (i = 14; i < 20; i++) {
        d2h_fis[i] = 0;
    }

    /* Update shadow registers: */
    pr->tfdata = (ad->port.ifs[0].error << 8) |
        ad->port.ifs[0].status;

    /* TFES IRQ is always raised if ERR_STAT is set, regardless of I bit. */
    if (d2h_fis[2] & ERR_STAT) {
        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES);
    } else if (d2h_fis_i) {
        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_DHRS);
    }

    return true;
}

static int prdt_tbl_entry_size(const AHCI_SG *tbl)
{
    /* flags_size is zero-based */
    return (le32_to_cpu(tbl->flags_size) & AHCI_PRDT_SIZE_MASK) + 1;
}

/**
 * Fetch entries in a guest-provided PRDT and convert it into a QEMU SGlist.
 * @ad: The AHCIDevice for whom we are building the SGList.
 * @sglist: The SGList target to add PRD entries to.
 * @cmd: The AHCI Command Header that describes where the PRDT is.
 * @limit: The remaining size of the S/ATA transaction, in bytes.
 * @offset: The number of bytes already transferred, in bytes.
 *
 * The AHCI PRDT can describe up to 256GiB. S/ATA only support transactions of
 * up to 32MiB as of ATA8-ACS3 rev 1b, assuming a 512 byte sector size. We stop
 * building the sglist from the PRDT as soon as we hit @limit bytes,
 * which is <= INT32_MAX/2GiB.
 */
static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist,
                                AHCICmdHdr *cmd, int64_t limit, uint64_t offset)
{
    uint16_t opts = le16_to_cpu(cmd->opts);
    uint16_t prdtl = le16_to_cpu(cmd->prdtl);
    uint64_t cfis_addr = le64_to_cpu(cmd->tbl_addr);
    uint64_t prdt_addr = cfis_addr + 0x80;
    dma_addr_t prdt_len = (prdtl * sizeof(AHCI_SG));
    dma_addr_t real_prdt_len = prdt_len;
    uint8_t *prdt;
    int i;
    int r = 0;
    uint64_t sum = 0;
    int off_idx = -1;
    int64_t off_pos = -1;
    IDEBus *bus = &ad->port;
    BusState *qbus = BUS(bus);

    trace_ahci_populate_sglist(ad->hba, ad->port_no);

    if (!prdtl) {
        trace_ahci_populate_sglist_no_prdtl(ad->hba, ad->port_no, opts);
        return -1;
    }

    /* map PRDT */
    if (!(prdt = dma_memory_map(ad->hba->as, prdt_addr, &prdt_len,
                                DMA_DIRECTION_TO_DEVICE,
                                MEMTXATTRS_UNSPECIFIED))){
        trace_ahci_populate_sglist_no_map(ad->hba, ad->port_no);
        return -1;
    }

    if (prdt_len < real_prdt_len) {
        trace_ahci_populate_sglist_short_map(ad->hba, ad->port_no);
        r = -1;
        goto out;
    }

    /* Get entries in the PRDT, init a qemu sglist accordingly */
    if (prdtl > 0) {
        AHCI_SG *tbl = (AHCI_SG *)prdt;
        int tbl_entry_size = 0;

        sum = 0;
        for (i = 0; i < prdtl; i++) {
            tbl_entry_size = prdt_tbl_entry_size(&tbl[i]);
            if (offset < (sum + tbl_entry_size)) {
                off_idx = i;
                off_pos = offset - sum;
                break;
            }
            sum += tbl_entry_size;
        }
        if ((off_idx == -1) || (off_pos < 0) || (off_pos > tbl_entry_size)) {
            trace_ahci_populate_sglist_bad_offset(ad->hba, ad->port_no,
                                                  off_idx, off_pos);
            r = -1;
            goto out;
        }

        qemu_sglist_init(sglist, qbus->parent, (prdtl - off_idx),
                         ad->hba->as);
        qemu_sglist_add(sglist, le64_to_cpu(tbl[off_idx].addr) + off_pos,
                        MIN(prdt_tbl_entry_size(&tbl[off_idx]) - off_pos,
                            limit));

        for (i = off_idx + 1; i < prdtl && sglist->size < limit; i++) {
            qemu_sglist_add(sglist, le64_to_cpu(tbl[i].addr),
                            MIN(prdt_tbl_entry_size(&tbl[i]),
                                limit - sglist->size));
        }
    }

out:
    dma_memory_unmap(ad->hba->as, prdt, prdt_len,
                     DMA_DIRECTION_TO_DEVICE, prdt_len);
    return r;
}

static void ncq_err(NCQTransferState *ncq_tfs)
{
    IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];

    ide_state->error = ABRT_ERR;
    ide_state->status = READY_STAT | ERR_STAT;
    qemu_sglist_destroy(&ncq_tfs->sglist);
    ncq_tfs->used = 0;
}

static void ncq_finish(NCQTransferState *ncq_tfs)
{
    /* If we didn't error out, set our finished bit. Errored commands
     * do not get a bit set for the SDB FIS ACT register, nor do they
     * clear the outstanding bit in scr_act (PxSACT). */
    if (ncq_tfs->used) {
        ncq_tfs->drive->finished |= (1 << ncq_tfs->tag);
    }

    ahci_write_fis_sdb(ncq_tfs->drive->hba, ncq_tfs);

    trace_ncq_finish(ncq_tfs->drive->hba, ncq_tfs->drive->port_no,
                     ncq_tfs->tag);

    block_acct_done(blk_get_stats(ncq_tfs->drive->port.ifs[0].blk),
                    &ncq_tfs->acct);
    qemu_sglist_destroy(&ncq_tfs->sglist);
    ncq_tfs->used = 0;
}

static void ncq_cb(void *opaque, int ret)
{
    NCQTransferState *ncq_tfs = (NCQTransferState *)opaque;
    IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];

    ncq_tfs->aiocb = NULL;

    if (ret < 0) {
        bool is_read = ncq_tfs->cmd == READ_FPDMA_QUEUED;
        BlockErrorAction action = blk_get_error_action(ide_state->blk,
                                                       is_read, -ret);
        if (action == BLOCK_ERROR_ACTION_STOP) {
            ncq_tfs->halt = true;
            ide_state->bus->error_status = IDE_RETRY_HBA;
        } else if (action == BLOCK_ERROR_ACTION_REPORT) {
            ncq_err(ncq_tfs);
        }
        blk_error_action(ide_state->blk, action, is_read, -ret);
    } else {
        ide_state->status = READY_STAT | SEEK_STAT;
    }

    if (!ncq_tfs->halt) {
        ncq_finish(ncq_tfs);
    }
}

static int is_ncq(uint8_t ata_cmd)
{
    /* Based on SATA 3.2 section 13.6.3.2 */
    switch (ata_cmd) {
    case READ_FPDMA_QUEUED:
    case WRITE_FPDMA_QUEUED:
    case NCQ_NON_DATA:
    case RECEIVE_FPDMA_QUEUED:
    case SEND_FPDMA_QUEUED:
        return 1;
    default:
        return 0;
    }
}

static void execute_ncq_command(NCQTransferState *ncq_tfs)
{
    AHCIDevice *ad = ncq_tfs->drive;
    IDEState *ide_state = &ad->port.ifs[0];
    int port = ad->port_no;

    g_assert(is_ncq(ncq_tfs->cmd));
    ncq_tfs->halt = false;

    switch (ncq_tfs->cmd) {
    case READ_FPDMA_QUEUED:
        trace_execute_ncq_command_read(ad->hba, port, ncq_tfs->tag,
                                       ncq_tfs->sector_count, ncq_tfs->lba);
        dma_acct_start(ide_state->blk, &ncq_tfs->acct,
                       &ncq_tfs->sglist, BLOCK_ACCT_READ);
        ncq_tfs->aiocb = dma_blk_read(ide_state->blk, &ncq_tfs->sglist,
                                      ncq_tfs->lba << BDRV_SECTOR_BITS,
                                      BDRV_SECTOR_SIZE,
                                      ncq_cb, ncq_tfs);
        break;
    case WRITE_FPDMA_QUEUED:
        trace_execute_ncq_command_write(ad->hba, port, ncq_tfs->tag,
                                        ncq_tfs->sector_count, ncq_tfs->lba);
        dma_acct_start(ide_state->blk, &ncq_tfs->acct,
                       &ncq_tfs->sglist, BLOCK_ACCT_WRITE);
        ncq_tfs->aiocb = dma_blk_write(ide_state->blk, &ncq_tfs->sglist,
                                       ncq_tfs->lba << BDRV_SECTOR_BITS,
                                       BDRV_SECTOR_SIZE,
                                       ncq_cb, ncq_tfs);
        break;
    default:
        trace_execute_ncq_command_unsup(ad->hba, port,
                                        ncq_tfs->tag, ncq_tfs->cmd);
        ncq_err(ncq_tfs);
    }
}


static void process_ncq_command(AHCIState *s, int port, const uint8_t *cmd_fis,
                                uint8_t slot)
{
    AHCIDevice *ad = &s->dev[port];
    const NCQFrame *ncq_fis = (NCQFrame *)cmd_fis;
    uint8_t tag = ncq_fis->tag >> 3;
    NCQTransferState *ncq_tfs = &ad->ncq_tfs[tag];
    size_t size;

    g_assert(is_ncq(ncq_fis->command));
    if (ncq_tfs->used) {
        /* error - already in use */
        qemu_log_mask(LOG_GUEST_ERROR, "%s: tag %d already used\n",
                      __func__, tag);
        return;
    }

    /*
     * A NCQ command clears the bit in PxCI after the command has been QUEUED
     * successfully (ERROR not set, BUSY and DRQ cleared).
     *
     * For NCQ commands, PxCI will always be cleared here.
     *
     * (Once the NCQ command is COMPLETED, the device will send a SDB FIS with
     * the interrupt bit set, which will clear PxSACT and raise an interrupt.)
     */
    ahci_clear_cmd_issue(ad, slot);

    /*
     * In reality, for NCQ commands, PxCI is cleared after receiving a D2H FIS
     * without the interrupt bit set, but since ahci_write_fis_d2h() can raise
     * an IRQ on error, we need to call them in reverse order.
     */
    ahci_write_fis_d2h(ad, false);

    ncq_tfs->used = 1;
    ncq_tfs->drive = ad;
    ncq_tfs->slot = slot;
    ncq_tfs->cmdh = &((AHCICmdHdr *)ad->lst)[slot];
    ncq_tfs->cmd = ncq_fis->command;
    ncq_tfs->lba = ((uint64_t)ncq_fis->lba5 << 40) |
                   ((uint64_t)ncq_fis->lba4 << 32) |
                   ((uint64_t)ncq_fis->lba3 << 24) |
                   ((uint64_t)ncq_fis->lba2 << 16) |
                   ((uint64_t)ncq_fis->lba1 << 8) |
                   (uint64_t)ncq_fis->lba0;
    ncq_tfs->tag = tag;

    /* Sanity-check the NCQ packet */
    if (tag != slot) {
        trace_process_ncq_command_mismatch(s, port, tag, slot);
    }

    if (ncq_fis->aux0 || ncq_fis->aux1 || ncq_fis->aux2 || ncq_fis->aux3) {
        trace_process_ncq_command_aux(s, port, tag);
    }
    if (ncq_fis->prio || ncq_fis->icc) {
        trace_process_ncq_command_prioicc(s, port, tag);
    }
    if (ncq_fis->fua & NCQ_FIS_FUA_MASK) {
        trace_process_ncq_command_fua(s, port, tag);
    }
    if (ncq_fis->tag & NCQ_FIS_RARC_MASK) {
        trace_process_ncq_command_rarc(s, port, tag);
    }

    ncq_tfs->sector_count = ((ncq_fis->sector_count_high << 8) |
                             ncq_fis->sector_count_low);
    if (!ncq_tfs->sector_count) {
        ncq_tfs->sector_count = 0x10000;
    }
    size = ncq_tfs->sector_count * BDRV_SECTOR_SIZE;
    ahci_populate_sglist(ad, &ncq_tfs->sglist, ncq_tfs->cmdh, size, 0);

    if (ncq_tfs->sglist.size < size) {
        error_report("ahci: PRDT length for NCQ command (0x" DMA_ADDR_FMT ") "
                     "is smaller than the requested size (0x%zx)",
                     ncq_tfs->sglist.size, size);
        ncq_err(ncq_tfs);
        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_OFS);
        return;
    } else if (ncq_tfs->sglist.size != size) {
        trace_process_ncq_command_large(s, port, tag,
                                        ncq_tfs->sglist.size, size);
    }

    trace_process_ncq_command(s, port, tag,
                              ncq_fis->command,
                              ncq_tfs->lba,
                              ncq_tfs->lba + ncq_tfs->sector_count - 1);
    execute_ncq_command(ncq_tfs);
}

static AHCICmdHdr *get_cmd_header(AHCIState *s, uint8_t port, uint8_t slot)
{
    if (port >= s->ports || slot >= AHCI_MAX_CMDS) {
        return NULL;
    }

    return s->dev[port].lst ? &((AHCICmdHdr *)s->dev[port].lst)[slot] : NULL;
}

static void handle_reg_h2d_fis(AHCIState *s, int port,
                               uint8_t slot, const uint8_t *cmd_fis)
{
    IDEState *ide_state = &s->dev[port].port.ifs[0];
    AHCICmdHdr *cmd = get_cmd_header(s, port, slot);
    AHCIDevice *ad = &s->dev[port];
    uint16_t opts = le16_to_cpu(cmd->opts);

    if (cmd_fis[1] & 0x0F) {
        trace_handle_reg_h2d_fis_pmp(s, port, cmd_fis[1],
                                     cmd_fis[2], cmd_fis[3]);
        return;
    }

    if (cmd_fis[1] & 0x70) {
        trace_handle_reg_h2d_fis_res(s, port, cmd_fis[1],
                                     cmd_fis[2], cmd_fis[3]);
        return;
    }

    if (!(cmd_fis[1] & SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER)) {
        switch (s->dev[port].port_state) {
        case STATE_RUN:
            if (cmd_fis[15] & ATA_SRST) {
                s->dev[port].port_state = STATE_RESET;
                /*
                 * When setting SRST in the first H2D FIS in the reset sequence,
                 * the device does not send a D2H FIS. Host software thus has to
                 * set the "Clear Busy upon R_OK" bit such that PxCI (and BUSY)
                 * gets cleared. See AHCI 1.3.1, section 10.4.1 Software Reset.
                 */
                if (opts & AHCI_CMD_CLR_BUSY) {
                    ahci_clear_cmd_issue(ad, slot);
                }
            }
            break;
        case STATE_RESET:
            if (!(cmd_fis[15] & ATA_SRST)) {
                /*
                 * When clearing SRST in the second H2D FIS in the reset
                 * sequence, the device will execute diagnostics. When this is
                 * done, the device will send a D2H FIS with the good status.
                 * See SATA 3.5a Gold, section 11.4 Software reset protocol.
                 *
                 * This D2H FIS is the first D2H FIS received from the device,
                 * and is received regardless if the reset was performed by a
                 * COMRESET or by setting and clearing the SRST bit. Therefore,
                 * the logic for this is found in ahci_init_d2h() and not here.
                 */
                ahci_reset_port(s, port);
            }
            break;
        }
        return;
    }

    /* Check for NCQ command */
    if (is_ncq(cmd_fis[2])) {
        process_ncq_command(s, port, cmd_fis, slot);
        return;
    }

    /* Decompose the FIS:
     * AHCI does not interpret FIS packets, it only forwards them.
     * SATA 1.0 describes how to decode LBA28 and CHS FIS packets.
     * Later specifications, e.g, SATA 3.2, describe LBA48 FIS packets.
     *
     * ATA4 describes sector number for LBA28/CHS commands.
     * ATA6 describes sector number for LBA48 commands.
     * ATA8 deprecates CHS fully, describing only LBA28/48.
     *
     * We dutifully convert the FIS into IDE registers, and allow the
     * core layer to interpret them as needed. */
    ide_state->feature = cmd_fis[3];
    ide_state->sector = cmd_fis[4];      /* LBA 7:0 */
    ide_state->lcyl = cmd_fis[5];        /* LBA 15:8  */
    ide_state->hcyl = cmd_fis[6];        /* LBA 23:16 */
    ide_state->select = cmd_fis[7];      /* LBA 27:24 (LBA28) */
    ide_state->hob_sector = cmd_fis[8];  /* LBA 31:24 */
    ide_state->hob_lcyl = cmd_fis[9];    /* LBA 39:32 */
    ide_state->hob_hcyl = cmd_fis[10];   /* LBA 47:40 */
    ide_state->hob_feature = cmd_fis[11];
    ide_state->nsector = (int64_t)((cmd_fis[13] << 8) | cmd_fis[12]);
    /* 14, 16, 17, 18, 19: Reserved (SATA 1.0) */
    /* 15: Only valid when UPDATE_COMMAND not set. */

    /* Copy the ACMD field (ATAPI packet, if any) from the AHCI command
     * table to ide_state->io_buffer */
    if (opts & AHCI_CMD_ATAPI) {
        memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10);
        if (trace_event_get_state_backends(TRACE_HANDLE_REG_H2D_FIS_DUMP)) {
            char *pretty_fis = ahci_pretty_buffer_fis(ide_state->io_buffer, 0x10);
            trace_handle_reg_h2d_fis_dump(s, port, pretty_fis);
            g_free(pretty_fis);
        }
    }

    ide_state->error = 0;
    s->dev[port].done_first_drq = false;
    /* Reset transferred byte counter */
    cmd->status = 0;

    /*
     * A non-NCQ command clears the bit in PxCI after the command has COMPLETED
     * successfully (ERROR not set, BUSY and DRQ cleared).
     *
     * For non-NCQ commands, PxCI will always be cleared by ahci_cmd_done().
     */
    ad->busy_slot = slot;

    /* We're ready to process the command in FIS byte 2. */
    ide_bus_exec_cmd(&s->dev[port].port, cmd_fis[2]);
}

static void handle_cmd(AHCIState *s, int port, uint8_t slot)
{
    IDEState *ide_state;
    uint64_t tbl_addr;
    AHCICmdHdr *cmd;
    uint8_t *cmd_fis;
    dma_addr_t cmd_len;

    if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
        /* Engine currently busy, try again later */
        trace_handle_cmd_busy(s, port);
        return;
    }

    if (!s->dev[port].lst) {
        trace_handle_cmd_nolist(s, port);
        return;
    }
    cmd = get_cmd_header(s, port, slot);
    /* remember current slot handle for later */
    s->dev[port].cur_cmd = cmd;

    /* The device we are working for */
    ide_state = &s->dev[port].port.ifs[0];
    if (!ide_state->blk) {
        trace_handle_cmd_badport(s, port);
        return;
    }

    tbl_addr = le64_to_cpu(cmd->tbl_addr);
    cmd_len = 0x80;
    cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
                             DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED);
    if (!cmd_fis) {
        trace_handle_cmd_badfis(s, port);
        return;
    } else if (cmd_len != 0x80) {
        ahci_trigger_irq(s, &s->dev[port], AHCI_PORT_IRQ_BIT_HBFS);
        trace_handle_cmd_badmap(s, port, cmd_len);
        goto out;
    }
    if (trace_event_get_state_backends(TRACE_HANDLE_CMD_FIS_DUMP)) {
        char *pretty_fis = ahci_pretty_buffer_fis(cmd_fis, 0x80);
        trace_handle_cmd_fis_dump(s, port, pretty_fis);
        g_free(pretty_fis);
    }
    switch (cmd_fis[0]) {
        case SATA_FIS_TYPE_REGISTER_H2D:
            handle_reg_h2d_fis(s, port, slot, cmd_fis);
            break;
        default:
            trace_handle_cmd_unhandled_fis(s, port,
                                           cmd_fis[0], cmd_fis[1], cmd_fis[2]);
            break;
    }

out:
    dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_TO_DEVICE,
                     cmd_len);
}

/* Transfer PIO data between RAM and device */
static void ahci_pio_transfer(const IDEDMA *dma)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
    IDEState *s = &ad->port.ifs[0];
    uint32_t size = (uint32_t)(s->data_end - s->data_ptr);
    /* write == ram -> device */
    uint16_t opts = le16_to_cpu(ad->cur_cmd->opts);
    int is_write = opts & AHCI_CMD_WRITE;
    int is_atapi = opts & AHCI_CMD_ATAPI;
    int has_sglist = 0;
    bool pio_fis_i;

    /* The PIO Setup FIS is received prior to transfer, but the interrupt
     * is only triggered after data is received.
     *
     * The device only sets the 'I' bit in the PIO Setup FIS for device->host
     * requests (see "DPIOI1" in the SATA spec), or for host->device DRQs after
     * the first (see "DPIOO1").  The latter is consistent with the spec's
     * description of the PACKET protocol, where the command part of ATAPI requests
     * ("DPKT0") has the 'I' bit clear, while the data part of PIO ATAPI requests
     * ("DPKT4a" and "DPKT7") has the 'I' bit set for both directions for all DRQs.
     */
    pio_fis_i = ad->done_first_drq || (!is_atapi && !is_write);
    ahci_write_fis_pio(ad, size, pio_fis_i);

    if (is_atapi && !ad->done_first_drq) {
        /* already prepopulated iobuffer */
        goto out;
    }

    if (ahci_dma_prepare_buf(dma, size)) {
        has_sglist = 1;
    }

    trace_ahci_pio_transfer(ad->hba, ad->port_no, is_write ? "writ" : "read",
                            size, is_atapi ? "atapi" : "ata",
                            has_sglist ? "" : "o");

    if (has_sglist && size) {
        const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;

        if (is_write) {
            dma_buf_write(s->data_ptr, size, NULL, &s->sg, attrs);
        } else {
            dma_buf_read(s->data_ptr, size, NULL, &s->sg, attrs);
        }
    }

    /* Update number of transferred bytes, destroy sglist */
    dma_buf_commit(s, size);

out:
    /* declare that we processed everything */
    s->data_ptr = s->data_end;

    ad->done_first_drq = true;
    if (pio_fis_i) {
        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_PSS);
    }
}

static void ahci_start_dma(const IDEDMA *dma, IDEState *s,
                           BlockCompletionFunc *dma_cb)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
    trace_ahci_start_dma(ad->hba, ad->port_no);
    s->io_buffer_offset = 0;
    dma_cb(s, 0);
}

static void ahci_restart_dma(const IDEDMA *dma)
{
    /* Nothing to do, ahci_start_dma already resets s->io_buffer_offset.  */
}

/**
 * IDE/PIO restarts are handled by the core layer, but NCQ commands
 * need an extra kick from the AHCI HBA.
 */
static void ahci_restart(const IDEDMA *dma)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
    int i;

    for (i = 0; i < AHCI_MAX_CMDS; i++) {
        NCQTransferState *ncq_tfs = &ad->ncq_tfs[i];
        if (ncq_tfs->halt) {
            execute_ncq_command(ncq_tfs);
        }
    }
}

/**
 * Called in DMA and PIO R/W chains to read the PRDT.
 * Not shared with NCQ pathways.
 */
static int32_t ahci_dma_prepare_buf(const IDEDMA *dma, int32_t limit)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
    IDEState *s = &ad->port.ifs[0];

    if (ahci_populate_sglist(ad, &s->sg, ad->cur_cmd,
                             limit, s->io_buffer_offset) == -1) {
        trace_ahci_dma_prepare_buf_fail(ad->hba, ad->port_no);
        return -1;
    }
    s->io_buffer_size = s->sg.size;

    trace_ahci_dma_prepare_buf(ad->hba, ad->port_no, limit, s->io_buffer_size);
    return s->io_buffer_size;
}

/**
 * Updates the command header with a bytes-read value.
 * Called via dma_buf_commit, for both DMA and PIO paths.
 * sglist destruction is handled within dma_buf_commit.
 */
static void ahci_commit_buf(const IDEDMA *dma, uint32_t tx_bytes)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);

    tx_bytes += le32_to_cpu(ad->cur_cmd->status);
    ad->cur_cmd->status = cpu_to_le32(tx_bytes);
}

static int ahci_dma_rw_buf(const IDEDMA *dma, bool is_write)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
    IDEState *s = &ad->port.ifs[0];
    uint8_t *p = s->io_buffer + s->io_buffer_index;
    int l = s->io_buffer_size - s->io_buffer_index;

    if (ahci_populate_sglist(ad, &s->sg, ad->cur_cmd, l, s->io_buffer_offset)) {
        return 0;
    }

    if (is_write) {
        dma_buf_read(p, l, NULL, &s->sg, MEMTXATTRS_UNSPECIFIED);
    } else {
        dma_buf_write(p, l, NULL, &s->sg, MEMTXATTRS_UNSPECIFIED);
    }

    /* free sglist, update byte count */
    dma_buf_commit(s, l);
    s->io_buffer_index += l;

    trace_ahci_dma_rw_buf(ad->hba, ad->port_no, l);
    return 1;
}

static void ahci_clear_cmd_issue(AHCIDevice *ad, uint8_t slot)
{
    IDEState *ide_state = &ad->port.ifs[0];

    if (!(ide_state->status & ERR_STAT) &&
        !(ide_state->status & (BUSY_STAT | DRQ_STAT))) {
        ad->port_regs.cmd_issue &= ~(1 << slot);
    }
}

/* Non-NCQ command is done - This function is never called for NCQ commands. */
static void ahci_cmd_done(const IDEDMA *dma)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
    IDEState *ide_state = &ad->port.ifs[0];

    trace_ahci_cmd_done(ad->hba, ad->port_no);

    /* no longer busy */
    if (ad->busy_slot != -1) {
        ahci_clear_cmd_issue(ad, ad->busy_slot);
        ad->busy_slot = -1;
    }

    /*
     * In reality, for non-NCQ commands, PxCI is cleared after receiving a D2H
     * FIS with the interrupt bit set, but since ahci_write_fis_d2h() will raise
     * an IRQ, we need to call them in reverse order.
     */
    ahci_write_fis_d2h(ad, true);

    if (!(ide_state->status & ERR_STAT) &&
        ad->port_regs.cmd_issue && !ad->check_bh) {
        ad->check_bh = qemu_bh_new_guarded(ahci_check_cmd_bh, ad,
                                           &ad->mem_reentrancy_guard);
        qemu_bh_schedule(ad->check_bh);
    }
}

static void ahci_irq_set(void *opaque, int n, int level)
{
    qemu_log_mask(LOG_UNIMP, "ahci: IRQ#%d level:%d\n", n, level);
}

static const IDEDMAOps ahci_dma_ops = {
    .start_dma = ahci_start_dma,
    .restart = ahci_restart,
    .restart_dma = ahci_restart_dma,
    .pio_transfer = ahci_pio_transfer,
    .prepare_buf = ahci_dma_prepare_buf,
    .commit_buf = ahci_commit_buf,
    .rw_buf = ahci_dma_rw_buf,
    .cmd_done = ahci_cmd_done,
};

void ahci_init(AHCIState *s, DeviceState *qdev)
{
    /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
    memory_region_init_io(&s->mem, OBJECT(qdev), &ahci_mem_ops, s,
                          "ahci", AHCI_MEM_BAR_SIZE);
    memory_region_init_io(&s->idp, OBJECT(qdev), &ahci_idp_ops, s,
                          "ahci-idp", 32);
}

void ahci_realize(AHCIState *s, DeviceState *qdev, AddressSpace *as)
{
    qemu_irq *irqs;
    int i;

    s->as = as;
    assert(s->ports > 0);
    s->dev = g_new0(AHCIDevice, s->ports);
    ahci_reg_init(s);
    irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports);
    for (i = 0; i < s->ports; i++) {
        AHCIDevice *ad = &s->dev[i];

        ide_bus_init(&ad->port, sizeof(ad->port), qdev, i, 1);
        ide_bus_init_output_irq(&ad->port, irqs[i]);

        ad->hba = s;
        ad->port_no = i;
        ad->port.dma = &ad->dma;
        ad->port.dma->ops = &ahci_dma_ops;
        ide_bus_register_restart_cb(&ad->port);
    }
    g_free(irqs);
}

void ahci_uninit(AHCIState *s)
{
    int i, j;

    for (i = 0; i < s->ports; i++) {
        AHCIDevice *ad = &s->dev[i];

        for (j = 0; j < 2; j++) {
            ide_exit(&ad->port.ifs[j]);
        }
        object_unparent(OBJECT(&ad->port));
    }

    g_free(s->dev);
}

void ahci_reset(AHCIState *s)
{
    AHCIPortRegs *pr;
    int i;

    trace_ahci_reset(s);

    s->control_regs.irqstatus = 0;
    /* AHCI Enable (AE)
     * The implementation of this bit is dependent upon the value of the
     * CAP.SAM bit. If CAP.SAM is '0', then GHC.AE shall be read-write and
     * shall have a reset value of '0'. If CAP.SAM is '1', then AE shall be
     * read-only and shall have a reset value of '1'.
     *
     * We set HOST_CAP_AHCI so we must enable AHCI at reset.
     */
    s->control_regs.ghc = HOST_CTL_AHCI_EN;

    for (i = 0; i < s->ports; i++) {
        pr = &s->dev[i].port_regs;
        pr->irq_stat = 0;
        pr->irq_mask = 0;
        pr->scr_ctl = 0;
        pr->cmd = PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON;
        ahci_reset_port(s, i);
    }
}

static const VMStateDescription vmstate_ncq_tfs = {
    .name = "ncq state",
    .version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT32(sector_count, NCQTransferState),
        VMSTATE_UINT64(lba, NCQTransferState),
        VMSTATE_UINT8(tag, NCQTransferState),
        VMSTATE_UINT8(cmd, NCQTransferState),
        VMSTATE_UINT8(slot, NCQTransferState),
        VMSTATE_BOOL(used, NCQTransferState),
        VMSTATE_BOOL(halt, NCQTransferState),
        VMSTATE_END_OF_LIST()
    },
};

static const VMStateDescription vmstate_ahci_device = {
    .name = "ahci port",
    .version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_IDE_BUS(port, AHCIDevice),
        VMSTATE_IDE_DRIVE(port.ifs[0], AHCIDevice),
        VMSTATE_UINT32(port_state, AHCIDevice),
        VMSTATE_UINT32(finished, AHCIDevice),
        VMSTATE_UINT32(port_regs.lst_addr, AHCIDevice),
        VMSTATE_UINT32(port_regs.lst_addr_hi, AHCIDevice),
        VMSTATE_UINT32(port_regs.fis_addr, AHCIDevice),
        VMSTATE_UINT32(port_regs.fis_addr_hi, AHCIDevice),
        VMSTATE_UINT32(port_regs.irq_stat, AHCIDevice),
        VMSTATE_UINT32(port_regs.irq_mask, AHCIDevice),
        VMSTATE_UINT32(port_regs.cmd, AHCIDevice),
        VMSTATE_UINT32(port_regs.tfdata, AHCIDevice),
        VMSTATE_UINT32(port_regs.sig, AHCIDevice),
        VMSTATE_UINT32(port_regs.scr_stat, AHCIDevice),
        VMSTATE_UINT32(port_regs.scr_ctl, AHCIDevice),
        VMSTATE_UINT32(port_regs.scr_err, AHCIDevice),
        VMSTATE_UINT32(port_regs.scr_act, AHCIDevice),
        VMSTATE_UINT32(port_regs.cmd_issue, AHCIDevice),
        VMSTATE_BOOL(done_first_drq, AHCIDevice),
        VMSTATE_INT32(busy_slot, AHCIDevice),
        VMSTATE_BOOL(init_d2h_sent, AHCIDevice),
        VMSTATE_STRUCT_ARRAY(ncq_tfs, AHCIDevice, AHCI_MAX_CMDS,
                             1, vmstate_ncq_tfs, NCQTransferState),
        VMSTATE_END_OF_LIST()
    },
};

static int ahci_state_post_load(void *opaque, int version_id)
{
    int i, j;
    struct AHCIDevice *ad;
    NCQTransferState *ncq_tfs;
    AHCIPortRegs *pr;
    AHCIState *s = opaque;

    for (i = 0; i < s->ports; i++) {
        ad = &s->dev[i];
        pr = &ad->port_regs;

        if (!(pr->cmd & PORT_CMD_START) && (pr->cmd & PORT_CMD_LIST_ON)) {
            error_report("AHCI: DMA engine should be off, but status bit "
                         "indicates it is still running.");
            return -1;
        }
        if (!(pr->cmd & PORT_CMD_FIS_RX) && (pr->cmd & PORT_CMD_FIS_ON)) {
            error_report("AHCI: FIS RX engine should be off, but status bit "
                         "indicates it is still running.");
            return -1;
        }

        /* After a migrate, the DMA/FIS engines are "off" and
         * need to be conditionally restarted */
        pr->cmd &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON);
        if (ahci_cond_start_engines(ad) != 0) {
            return -1;
        }

        for (j = 0; j < AHCI_MAX_CMDS; j++) {
            ncq_tfs = &ad->ncq_tfs[j];
            ncq_tfs->drive = ad;

            if (ncq_tfs->used != ncq_tfs->halt) {
                return -1;
            }
            if (!ncq_tfs->halt) {
                continue;
            }
            if (!is_ncq(ncq_tfs->cmd)) {
                return -1;
            }
            if (ncq_tfs->slot != ncq_tfs->tag) {
                return -1;
            }
            /* If ncq_tfs->halt is justly set, the engine should be engaged,
             * and the command list buffer should be mapped. */
            ncq_tfs->cmdh = get_cmd_header(s, i, ncq_tfs->slot);
            if (!ncq_tfs->cmdh) {
                return -1;
            }
            ahci_populate_sglist(ncq_tfs->drive, &ncq_tfs->sglist,
                                 ncq_tfs->cmdh,
                                 ncq_tfs->sector_count * BDRV_SECTOR_SIZE,
                                 0);
            if (ncq_tfs->sector_count != ncq_tfs->sglist.size >> 9) {
                return -1;
            }
        }


        /*
         * If an error is present, ad->busy_slot will be valid and not -1.
         * In this case, an operation is waiting to resume and will re-check
         * for additional AHCI commands to execute upon completion.
         *
         * In the case where no error was present, busy_slot will be -1,
         * and we should check to see if there are additional commands waiting.
         */
        if (ad->busy_slot == -1) {
            check_cmd(s, i);
        } else {
            /* We are in the middle of a command, and may need to access
             * the command header in guest memory again. */
            if (ad->busy_slot < 0 || ad->busy_slot >= AHCI_MAX_CMDS) {
                return -1;
            }
            ad->cur_cmd = get_cmd_header(s, i, ad->busy_slot);
        }
    }

    return 0;
}

const VMStateDescription vmstate_ahci = {
    .name = "ahci",
    .version_id = 1,
    .post_load = ahci_state_post_load,
    .fields = (const VMStateField[]) {
        VMSTATE_STRUCT_VARRAY_POINTER_UINT32(dev, AHCIState, ports,
                                     vmstate_ahci_device, AHCIDevice),
        VMSTATE_UINT32(control_regs.cap, AHCIState),
        VMSTATE_UINT32(control_regs.ghc, AHCIState),
        VMSTATE_UINT32(control_regs.irqstatus, AHCIState),
        VMSTATE_UINT32(control_regs.impl, AHCIState),
        VMSTATE_UINT32(control_regs.version, AHCIState),
        VMSTATE_UINT32(idp_index, AHCIState),
        VMSTATE_UINT32_EQUAL(ports, AHCIState, NULL),
        VMSTATE_END_OF_LIST()
    },
};

void ahci_ide_create_devs(AHCIState *ahci, DriveInfo **hd)
{
    int i;

    for (i = 0; i < ahci->ports; i++) {
        if (hd[i] == NULL) {
            continue;
        }
        ide_bus_create_drive(&ahci->dev[i].port, 0, hd[i]);
    }
}
