/*
 * s390 PCI instructions
 *
 * Copyright 2014 IBM Corp.
 * Author(s): Frank Blaschka <frank.blaschka@de.ibm.com>
 *            Hong Bo Li <lihbbj@cn.ibm.com>
 *            Yi Min Zhao <zyimin@cn.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or (at
 * your option) any later version. See the COPYING file in the top-level
 * directory.
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/memop.h"
#include "exec/memory-internal.h"
#include "qemu/error-report.h"
#include "sysemu/hw_accel.h"
#include "hw/s390x/s390-pci-inst.h"
#include "hw/s390x/s390-pci-bus.h"
#include "hw/s390x/tod.h"

#ifndef DEBUG_S390PCI_INST
#define DEBUG_S390PCI_INST  0
#endif

#define DPRINTF(fmt, ...)                                          \
    do {                                                           \
        if (DEBUG_S390PCI_INST) {                                  \
            fprintf(stderr, "s390pci-inst: " fmt, ## __VA_ARGS__); \
        }                                                          \
    } while (0)

static inline void inc_dma_avail(S390PCIIOMMU *iommu)
{
    if (iommu->dma_limit) {
        iommu->dma_limit->avail++;
    }
}

static inline void dec_dma_avail(S390PCIIOMMU *iommu)
{
    if (iommu->dma_limit) {
        iommu->dma_limit->avail--;
    }
}

static void s390_set_status_code(CPUS390XState *env,
                                 uint8_t r, uint64_t status_code)
{
    env->regs[r] &= ~0xff000000ULL;
    env->regs[r] |= (status_code & 0xff) << 24;
}

static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc)
{
    S390PCIBusDevice *pbdev = NULL;
    S390pciState *s = s390_get_phb();
    uint32_t res_code, initial_l2, g_l2;
    int rc, i;
    uint64_t resume_token;

    rc = 0;
    if (lduw_p(&rrb->request.hdr.len) != 32) {
        res_code = CLP_RC_LEN;
        rc = -EINVAL;
        goto out;
    }

    if ((ldl_p(&rrb->request.fmt) & CLP_MASK_FMT) != 0) {
        res_code = CLP_RC_FMT;
        rc = -EINVAL;
        goto out;
    }

    if ((ldl_p(&rrb->request.fmt) & ~CLP_MASK_FMT) != 0 ||
        ldq_p(&rrb->request.reserved1) != 0) {
        res_code = CLP_RC_RESNOT0;
        rc = -EINVAL;
        goto out;
    }

    resume_token = ldq_p(&rrb->request.resume_token);

    if (resume_token) {
        pbdev = s390_pci_find_dev_by_idx(s, resume_token);
        if (!pbdev) {
            res_code = CLP_RC_LISTPCI_BADRT;
            rc = -EINVAL;
            goto out;
        }
    } else {
        pbdev = s390_pci_find_next_avail_dev(s, NULL);
    }

    if (lduw_p(&rrb->response.hdr.len) < 48) {
        res_code = CLP_RC_8K;
        rc = -EINVAL;
        goto out;
    }

    initial_l2 = lduw_p(&rrb->response.hdr.len);
    if ((initial_l2 - LIST_PCI_HDR_LEN) % sizeof(ClpFhListEntry)
        != 0) {
        res_code = CLP_RC_LEN;
        rc = -EINVAL;
        *cc = 3;
        goto out;
    }

    stl_p(&rrb->response.fmt, 0);
    stq_p(&rrb->response.reserved1, 0);
    stl_p(&rrb->response.mdd, FH_MASK_SHM);
    stw_p(&rrb->response.max_fn, PCI_MAX_FUNCTIONS);
    rrb->response.flags = UID_CHECKING_ENABLED;
    rrb->response.entry_size = sizeof(ClpFhListEntry);

    i = 0;
    g_l2 = LIST_PCI_HDR_LEN;
    while (g_l2 < initial_l2 && pbdev) {
        stw_p(&rrb->response.fh_list[i].device_id,
            pci_get_word(pbdev->pdev->config + PCI_DEVICE_ID));
        stw_p(&rrb->response.fh_list[i].vendor_id,
            pci_get_word(pbdev->pdev->config + PCI_VENDOR_ID));
        /* Ignore RESERVED devices. */
        stl_p(&rrb->response.fh_list[i].config,
            pbdev->state == ZPCI_FS_STANDBY ? 0 : 1 << 31);
        stl_p(&rrb->response.fh_list[i].fid, pbdev->fid);
        stl_p(&rrb->response.fh_list[i].fh, pbdev->fh);

        g_l2 += sizeof(ClpFhListEntry);
        /* Add endian check for DPRINTF? */
        DPRINTF("g_l2 %d vendor id 0x%x device id 0x%x fid 0x%x fh 0x%x\n",
                g_l2,
                lduw_p(&rrb->response.fh_list[i].vendor_id),
                lduw_p(&rrb->response.fh_list[i].device_id),
                ldl_p(&rrb->response.fh_list[i].fid),
                ldl_p(&rrb->response.fh_list[i].fh));
        pbdev = s390_pci_find_next_avail_dev(s, pbdev);
        i++;
    }

    if (!pbdev) {
        resume_token = 0;
    } else {
        resume_token = pbdev->fh & FH_MASK_INDEX;
    }
    stq_p(&rrb->response.resume_token, resume_token);
    stw_p(&rrb->response.hdr.len, g_l2);
    stw_p(&rrb->response.hdr.rsp, CLP_RC_OK);
out:
    if (rc) {
        DPRINTF("list pci failed rc 0x%x\n", rc);
        stw_p(&rrb->response.hdr.rsp, res_code);
    }
    return rc;
}

int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
{
    ClpReqHdr *reqh;
    ClpRspHdr *resh;
    S390PCIBusDevice *pbdev;
    uint32_t req_len;
    uint32_t res_len;
    uint8_t buffer[4096 * 2];
    uint8_t cc = 0;
    CPUS390XState *env = &cpu->env;
    S390pciState *s = s390_get_phb();
    int i;

    if (env->psw.mask & PSW_MASK_PSTATE) {
        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
        return 0;
    }

    if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer, sizeof(*reqh))) {
        s390_cpu_virt_mem_handle_exc(cpu, ra);
        return 0;
    }
    reqh = (ClpReqHdr *)buffer;
    req_len = lduw_p(&reqh->len);
    if (req_len < 16 || req_len > 8184 || (req_len % 8 != 0)) {
        s390_program_interrupt(env, PGM_OPERAND, ra);
        return 0;
    }

    if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer,
                               req_len + sizeof(*resh))) {
        s390_cpu_virt_mem_handle_exc(cpu, ra);
        return 0;
    }
    resh = (ClpRspHdr *)(buffer + req_len);
    res_len = lduw_p(&resh->len);
    if (res_len < 8 || res_len > 8176 || (res_len % 8 != 0)) {
        s390_program_interrupt(env, PGM_OPERAND, ra);
        return 0;
    }
    if ((req_len + res_len) > 8192) {
        s390_program_interrupt(env, PGM_OPERAND, ra);
        return 0;
    }

    if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer,
                               req_len + res_len)) {
        s390_cpu_virt_mem_handle_exc(cpu, ra);
        return 0;
    }

    if (req_len != 32) {
        stw_p(&resh->rsp, CLP_RC_LEN);
        goto out;
    }

    switch (lduw_p(&reqh->cmd)) {
    case CLP_LIST_PCI: {
        ClpReqRspListPci *rrb = (ClpReqRspListPci *)buffer;
        list_pci(rrb, &cc);
        break;
    }
    case CLP_SET_PCI_FN: {
        ClpReqSetPci *reqsetpci = (ClpReqSetPci *)reqh;
        ClpRspSetPci *ressetpci = (ClpRspSetPci *)resh;

        pbdev = s390_pci_find_dev_by_fh(s, ldl_p(&reqsetpci->fh));
        if (!pbdev) {
                stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FH);
                goto out;
        }

        switch (reqsetpci->oc) {
        case CLP_SET_ENABLE_PCI_FN:
            switch (reqsetpci->ndas) {
            case 0:
                stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_DMAAS);
                goto out;
            case 1:
                break;
            default:
                stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_RES);
                goto out;
            }

            if (pbdev->fh & FH_MASK_ENABLE) {
                stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP);
                goto out;
            }

            pbdev->fh |= FH_MASK_ENABLE;
            pbdev->state = ZPCI_FS_ENABLED;
            stl_p(&ressetpci->fh, pbdev->fh);
            stw_p(&ressetpci->hdr.rsp, CLP_RC_OK);
            break;
        case CLP_SET_DISABLE_PCI_FN:
            if (!(pbdev->fh & FH_MASK_ENABLE)) {
                stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP);
                goto out;
            }
            device_legacy_reset(DEVICE(pbdev));
            pbdev->fh &= ~FH_MASK_ENABLE;
            pbdev->state = ZPCI_FS_DISABLED;
            stl_p(&ressetpci->fh, pbdev->fh);
            stw_p(&ressetpci->hdr.rsp, CLP_RC_OK);
            break;
        default:
            DPRINTF("unknown set pci command\n");
            stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP);
            break;
        }
        break;
    }
    case CLP_QUERY_PCI_FN: {
        ClpReqQueryPci *reqquery = (ClpReqQueryPci *)reqh;
        ClpRspQueryPci *resquery = (ClpRspQueryPci *)resh;

        pbdev = s390_pci_find_dev_by_fh(s, ldl_p(&reqquery->fh));
        if (!pbdev) {
            DPRINTF("query pci no pci dev\n");
            stw_p(&resquery->hdr.rsp, CLP_RC_SETPCIFN_FH);
            goto out;
        }

        stq_p(&resquery->sdma, pbdev->zpci_fn.sdma);
        stq_p(&resquery->edma, pbdev->zpci_fn.edma);
        stw_p(&resquery->pchid, pbdev->zpci_fn.pchid);
        stw_p(&resquery->vfn, pbdev->zpci_fn.vfn);
        resquery->flags = pbdev->zpci_fn.flags;
        resquery->pfgid = pbdev->zpci_fn.pfgid;
        resquery->pft = pbdev->zpci_fn.pft;
        resquery->fmbl = pbdev->zpci_fn.fmbl;
        stl_p(&resquery->fid, pbdev->zpci_fn.fid);
        stl_p(&resquery->uid, pbdev->zpci_fn.uid);
        memcpy(resquery->pfip, pbdev->zpci_fn.pfip, CLP_PFIP_NR_SEGMENTS);
        memcpy(resquery->util_str, pbdev->zpci_fn.util_str, CLP_UTIL_STR_LEN);

        for (i = 0; i < PCI_BAR_COUNT; i++) {
            uint32_t data = pci_get_long(pbdev->pdev->config +
                PCI_BASE_ADDRESS_0 + (i * 4));

            stl_p(&resquery->bar[i], data);
            resquery->bar_size[i] = pbdev->pdev->io_regions[i].size ?
                                    ctz64(pbdev->pdev->io_regions[i].size) : 0;
            DPRINTF("bar %d addr 0x%x size 0x%" PRIx64 "barsize 0x%x\n", i,
                    ldl_p(&resquery->bar[i]),
                    pbdev->pdev->io_regions[i].size,
                    resquery->bar_size[i]);
        }

        stw_p(&resquery->hdr.rsp, CLP_RC_OK);
        break;
    }
    case CLP_QUERY_PCI_FNGRP: {
        ClpRspQueryPciGrp *resgrp = (ClpRspQueryPciGrp *)resh;

        ClpReqQueryPciGrp *reqgrp = (ClpReqQueryPciGrp *)reqh;
        S390PCIGroup *group;

        group = s390_group_find(reqgrp->g);
        if (!group) {
            /* We do not allow access to unknown groups */
            /* The group must have been obtained with a vfio device */
            stw_p(&resgrp->hdr.rsp, CLP_RC_QUERYPCIFG_PFGID);
            goto out;
        }
        resgrp->fr = group->zpci_group.fr;
        stq_p(&resgrp->dasm, group->zpci_group.dasm);
        stq_p(&resgrp->msia, group->zpci_group.msia);
        stw_p(&resgrp->mui, group->zpci_group.mui);
        stw_p(&resgrp->i, group->zpci_group.i);
        stw_p(&resgrp->maxstbl, group->zpci_group.maxstbl);
        resgrp->version = group->zpci_group.version;
        stw_p(&resgrp->hdr.rsp, CLP_RC_OK);
        break;
    }
    default:
        DPRINTF("unknown clp command\n");
        stw_p(&resh->rsp, CLP_RC_CMD);
        break;
    }

out:
    if (s390_cpu_virt_mem_write(cpu, env->regs[r2], r2, buffer,
                                req_len + res_len)) {
        s390_cpu_virt_mem_handle_exc(cpu, ra);
        return 0;
    }
    setcc(cpu, cc);
    return 0;
}

/**
 * Swap data contained in s390x big endian registers to little endian
 * PCI bars.
 *
 * @ptr: a pointer to a uint64_t data field
 * @len: the length of the valid data, must be 1,2,4 or 8
 */
static int zpci_endian_swap(uint64_t *ptr, uint8_t len)
{
    uint64_t data = *ptr;

    switch (len) {
    case 1:
        break;
    case 2:
        data = bswap16(data);
        break;
    case 4:
        data = bswap32(data);
        break;
    case 8:
        data = bswap64(data);
        break;
    default:
        return -EINVAL;
    }
    *ptr = data;
    return 0;
}

static MemoryRegion *s390_get_subregion(MemoryRegion *mr, uint64_t offset,
                                        uint8_t len)
{
    MemoryRegion *subregion;
    uint64_t subregion_size;

    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
        subregion_size = int128_get64(subregion->size);
        if ((offset >= subregion->addr) &&
            (offset + len) <= (subregion->addr + subregion_size)) {
            mr = subregion;
            break;
        }
    }
    return mr;
}

static MemTxResult zpci_read_bar(S390PCIBusDevice *pbdev, uint8_t pcias,
                                 uint64_t offset, uint64_t *data, uint8_t len)
{
    MemoryRegion *mr;

    mr = pbdev->pdev->io_regions[pcias].memory;
    mr = s390_get_subregion(mr, offset, len);
    offset -= mr->addr;
    return memory_region_dispatch_read(mr, offset, data,
                                       size_memop(len) | MO_BE,
                                       MEMTXATTRS_UNSPECIFIED);
}

int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
{
    CPUS390XState *env = &cpu->env;
    S390PCIBusDevice *pbdev;
    uint64_t offset;
    uint64_t data;
    MemTxResult result;
    uint8_t len;
    uint32_t fh;
    uint8_t pcias;

    if (env->psw.mask & PSW_MASK_PSTATE) {
        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
        return 0;
    }

    if (r2 & 0x1) {
        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
        return 0;
    }

    fh = env->regs[r2] >> 32;
    pcias = (env->regs[r2] >> 16) & 0xf;
    len = env->regs[r2] & 0xf;
    offset = env->regs[r2 + 1];

    if (!(fh & FH_MASK_ENABLE)) {
        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
        return 0;
    }

    pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
    if (!pbdev) {
        DPRINTF("pcilg no pci dev\n");
        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
        return 0;
    }

    switch (pbdev->state) {
    case ZPCI_FS_PERMANENT_ERROR:
    case ZPCI_FS_ERROR:
        setcc(cpu, ZPCI_PCI_LS_ERR);
        s390_set_status_code(env, r2, ZPCI_PCI_ST_BLOCKED);
        return 0;
    default:
        break;
    }

    switch (pcias) {
    case ZPCI_IO_BAR_MIN...ZPCI_IO_BAR_MAX:
        if (!len || (len > (8 - (offset & 0x7)))) {
            s390_program_interrupt(env, PGM_OPERAND, ra);
            return 0;
        }
        result = zpci_read_bar(pbdev, pcias, offset, &data, len);
        if (result != MEMTX_OK) {
            s390_program_interrupt(env, PGM_OPERAND, ra);
            return 0;
        }
        break;
    case ZPCI_CONFIG_BAR:
        if (!len || (len > (4 - (offset & 0x3))) || len == 3) {
            s390_program_interrupt(env, PGM_OPERAND, ra);
            return 0;
        }
        data =  pci_host_config_read_common(
                   pbdev->pdev, offset, pci_config_size(pbdev->pdev), len);

        if (zpci_endian_swap(&data, len)) {
            s390_program_interrupt(env, PGM_OPERAND, ra);
            return 0;
        }
        break;
    default:
        DPRINTF("pcilg invalid space\n");
        setcc(cpu, ZPCI_PCI_LS_ERR);
        s390_set_status_code(env, r2, ZPCI_PCI_ST_INVAL_AS);
        return 0;
    }

    pbdev->fmb.counter[ZPCI_FMB_CNT_LD]++;

    env->regs[r1] = data;
    setcc(cpu, ZPCI_PCI_LS_OK);
    return 0;
}

static MemTxResult zpci_write_bar(S390PCIBusDevice *pbdev, uint8_t pcias,
                                  uint64_t offset, uint64_t data, uint8_t len)
{
    MemoryRegion *mr;

    mr = pbdev->pdev->io_regions[pcias].memory;
    mr = s390_get_subregion(mr, offset, len);
    offset -= mr->addr;
    return memory_region_dispatch_write(mr, offset, data,
                                        size_memop(len) | MO_BE,
                                        MEMTXATTRS_UNSPECIFIED);
}

int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
{
    CPUS390XState *env = &cpu->env;
    uint64_t offset, data;
    S390PCIBusDevice *pbdev;
    MemTxResult result;
    uint8_t len;
    uint32_t fh;
    uint8_t pcias;

    if (env->psw.mask & PSW_MASK_PSTATE) {
        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
        return 0;
    }

    if (r2 & 0x1) {
        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
        return 0;
    }

    fh = env->regs[r2] >> 32;
    pcias = (env->regs[r2] >> 16) & 0xf;
    len = env->regs[r2] & 0xf;
    offset = env->regs[r2 + 1];
    data = env->regs[r1];

    if (!(fh & FH_MASK_ENABLE)) {
        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
        return 0;
    }

    pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
    if (!pbdev) {
        DPRINTF("pcistg no pci dev\n");
        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
        return 0;
    }

    switch (pbdev->state) {
    /* ZPCI_FS_RESERVED, ZPCI_FS_STANDBY and ZPCI_FS_DISABLED
     * are already covered by the FH_MASK_ENABLE check above
     */
    case ZPCI_FS_PERMANENT_ERROR:
    case ZPCI_FS_ERROR:
        setcc(cpu, ZPCI_PCI_LS_ERR);
        s390_set_status_code(env, r2, ZPCI_PCI_ST_BLOCKED);
        return 0;
    default:
        break;
    }

    switch (pcias) {
        /* A ZPCI PCI card may use any BAR from BAR 0 to BAR 5 */
    case ZPCI_IO_BAR_MIN...ZPCI_IO_BAR_MAX:
        /* Check length:
         * A length of 0 is invalid and length should not cross a double word
         */
        if (!len || (len > (8 - (offset & 0x7)))) {
            s390_program_interrupt(env, PGM_OPERAND, ra);
            return 0;
        }

        result = zpci_write_bar(pbdev, pcias, offset, data, len);
        if (result != MEMTX_OK) {
            s390_program_interrupt(env, PGM_OPERAND, ra);
            return 0;
        }
        break;
    case ZPCI_CONFIG_BAR:
        /* ZPCI uses the pseudo BAR number 15 as configuration space */
        /* possible access lengths are 1,2,4 and must not cross a word */
        if (!len || (len > (4 - (offset & 0x3))) || len == 3) {
            s390_program_interrupt(env, PGM_OPERAND, ra);
            return 0;
        }
        /* len = 1,2,4 so we do not need to test */
        zpci_endian_swap(&data, len);
        pci_host_config_write_common(pbdev->pdev, offset,
                                     pci_config_size(pbdev->pdev),
                                     data, len);
        break;
    default:
        DPRINTF("pcistg invalid space\n");
        setcc(cpu, ZPCI_PCI_LS_ERR);
        s390_set_status_code(env, r2, ZPCI_PCI_ST_INVAL_AS);
        return 0;
    }

    pbdev->fmb.counter[ZPCI_FMB_CNT_ST]++;

    setcc(cpu, ZPCI_PCI_LS_OK);
    return 0;
}

static uint32_t s390_pci_update_iotlb(S390PCIIOMMU *iommu,
                                      S390IOTLBEntry *entry)
{
    S390IOTLBEntry *cache = g_hash_table_lookup(iommu->iotlb, &entry->iova);
    IOMMUTLBEvent event = {
        .type = entry->perm ? IOMMU_NOTIFIER_MAP : IOMMU_NOTIFIER_UNMAP,
        .entry = {
            .target_as = &address_space_memory,
            .iova = entry->iova,
            .translated_addr = entry->translated_addr,
            .perm = entry->perm,
            .addr_mask = ~PAGE_MASK,
        },
    };

    if (event.type == IOMMU_NOTIFIER_UNMAP) {
        if (!cache) {
            goto out;
        }
        g_hash_table_remove(iommu->iotlb, &entry->iova);
        inc_dma_avail(iommu);
    } else {
        if (cache) {
            if (cache->perm == entry->perm &&
                cache->translated_addr == entry->translated_addr) {
                goto out;
            }

            event.type = IOMMU_NOTIFIER_UNMAP;
            event.entry.perm = IOMMU_NONE;
            memory_region_notify_iommu(&iommu->iommu_mr, 0, event);
            event.type = IOMMU_NOTIFIER_MAP;
            event.entry.perm = entry->perm;
        }

        cache = g_new(S390IOTLBEntry, 1);
        cache->iova = entry->iova;
        cache->translated_addr = entry->translated_addr;
        cache->len = PAGE_SIZE;
        cache->perm = entry->perm;
        g_hash_table_replace(iommu->iotlb, &cache->iova, cache);
        dec_dma_avail(iommu);
    }

    memory_region_notify_iommu(&iommu->iommu_mr, 0, event);

out:
    return iommu->dma_limit ? iommu->dma_limit->avail : 1;
}

int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
{
    CPUS390XState *env = &cpu->env;
    uint32_t fh;
    uint16_t error = 0;
    S390PCIBusDevice *pbdev;
    S390PCIIOMMU *iommu;
    S390IOTLBEntry entry;
    hwaddr start, end;
    uint32_t dma_avail;

    if (env->psw.mask & PSW_MASK_PSTATE) {
        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
        return 0;
    }

    if (r2 & 0x1) {
        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
        return 0;
    }

    fh = env->regs[r1] >> 32;
    start = env->regs[r2];
    end = start + env->regs[r2 + 1];

    pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
    if (!pbdev) {
        DPRINTF("rpcit no pci dev\n");
        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
        return 0;
    }

    switch (pbdev->state) {
    case ZPCI_FS_RESERVED:
    case ZPCI_FS_STANDBY:
    case ZPCI_FS_DISABLED:
    case ZPCI_FS_PERMANENT_ERROR:
        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
        return 0;
    case ZPCI_FS_ERROR:
        setcc(cpu, ZPCI_PCI_LS_ERR);
        s390_set_status_code(env, r1, ZPCI_MOD_ST_ERROR_RECOVER);
        return 0;
    default:
        break;
    }

    iommu = pbdev->iommu;
    if (iommu->dma_limit) {
        dma_avail = iommu->dma_limit->avail;
    } else {
        dma_avail = 1;
    }
    if (!iommu->g_iota) {
        error = ERR_EVENT_INVALAS;
        goto err;
    }

    if (end < iommu->pba || start > iommu->pal) {
        error = ERR_EVENT_OORANGE;
        goto err;
    }

    while (start < end) {
        error = s390_guest_io_table_walk(iommu->g_iota, start, &entry);
        if (error) {
            break;
        }

        start += entry.len;
        while (entry.iova < start && entry.iova < end &&
               (dma_avail > 0 || entry.perm == IOMMU_NONE)) {
            dma_avail = s390_pci_update_iotlb(iommu, &entry);
            entry.iova += PAGE_SIZE;
            entry.translated_addr += PAGE_SIZE;
        }
    }
err:
    if (error) {
        pbdev->state = ZPCI_FS_ERROR;
        setcc(cpu, ZPCI_PCI_LS_ERR);
        s390_set_status_code(env, r1, ZPCI_PCI_ST_FUNC_IN_ERR);
        s390_pci_generate_error_event(error, pbdev->fh, pbdev->fid, start, 0);
    } else {
        pbdev->fmb.counter[ZPCI_FMB_CNT_RPCIT]++;
        if (dma_avail > 0) {
            setcc(cpu, ZPCI_PCI_LS_OK);
        } else {
            /* vfio DMA mappings are exhausted, trigger a RPCIT */
            setcc(cpu, ZPCI_PCI_LS_ERR);
            s390_set_status_code(env, r1, ZPCI_RPCIT_ST_INSUFF_RES);
        }
    }
    return 0;
}

int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
                        uint8_t ar, uintptr_t ra)
{
    CPUS390XState *env = &cpu->env;
    S390PCIBusDevice *pbdev;
    MemoryRegion *mr;
    MemTxResult result;
    uint64_t offset;
    int i;
    uint32_t fh;
    uint8_t pcias;
    uint16_t len;
    uint8_t buffer[128];

    if (env->psw.mask & PSW_MASK_PSTATE) {
        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
        return 0;
    }

    fh = env->regs[r1] >> 32;
    pcias = (env->regs[r1] >> 16) & 0xf;
    len = env->regs[r1] & 0x1fff;
    offset = env->regs[r3];

    if (!(fh & FH_MASK_ENABLE)) {
        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
        return 0;
    }

    pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
    if (!pbdev) {
        DPRINTF("pcistb no pci dev fh 0x%x\n", fh);
        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
        return 0;
    }

    switch (pbdev->state) {
    case ZPCI_FS_PERMANENT_ERROR:
    case ZPCI_FS_ERROR:
        setcc(cpu, ZPCI_PCI_LS_ERR);
        s390_set_status_code(env, r1, ZPCI_PCI_ST_BLOCKED);
        return 0;
    default:
        break;
    }

    if (pcias > ZPCI_IO_BAR_MAX) {
        DPRINTF("pcistb invalid space\n");
        setcc(cpu, ZPCI_PCI_LS_ERR);
        s390_set_status_code(env, r1, ZPCI_PCI_ST_INVAL_AS);
        return 0;
    }

    /* Verify the address, offset and length */
    /* offset must be a multiple of 8 */
    if (offset % 8) {
        goto specification_error;
    }
    /* Length must be greater than 8, a multiple of 8 */
    /* and not greater than maxstbl */
    if ((len <= 8) || (len % 8) ||
        (len > pbdev->pci_group->zpci_group.maxstbl)) {
        goto specification_error;
    }
    /* Do not cross a 4K-byte boundary */
    if (((offset & 0xfff) + len) > 0x1000) {
        goto specification_error;
    }
    /* Guest address must be double word aligned */
    if (gaddr & 0x07UL) {
        goto specification_error;
    }

    mr = pbdev->pdev->io_regions[pcias].memory;
    mr = s390_get_subregion(mr, offset, len);
    offset -= mr->addr;

    for (i = 0; i < len; i += 8) {
        if (!memory_region_access_valid(mr, offset + i, 8, true,
                                        MEMTXATTRS_UNSPECIFIED)) {
            s390_program_interrupt(env, PGM_OPERAND, ra);
            return 0;
        }
    }

    if (s390_cpu_virt_mem_read(cpu, gaddr, ar, buffer, len)) {
        s390_cpu_virt_mem_handle_exc(cpu, ra);
        return 0;
    }

    for (i = 0; i < len / 8; i++) {
        result = memory_region_dispatch_write(mr, offset + i * 8,
                                              ldq_p(buffer + i * 8),
                                              MO_64, MEMTXATTRS_UNSPECIFIED);
        if (result != MEMTX_OK) {
            s390_program_interrupt(env, PGM_OPERAND, ra);
            return 0;
        }
    }

    pbdev->fmb.counter[ZPCI_FMB_CNT_STB]++;

    setcc(cpu, ZPCI_PCI_LS_OK);
    return 0;

specification_error:
    s390_program_interrupt(env, PGM_SPECIFICATION, ra);
    return 0;
}

static int reg_irqs(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib)
{
    int ret, len;
    uint8_t isc = FIB_DATA_ISC(ldl_p(&fib.data));

    pbdev->routes.adapter.adapter_id = css_get_adapter_id(
                                       CSS_IO_ADAPTER_PCI, isc);
    pbdev->summary_ind = get_indicator(ldq_p(&fib.aisb), sizeof(uint64_t));
    len = BITS_TO_LONGS(FIB_DATA_NOI(ldl_p(&fib.data))) * sizeof(unsigned long);
    pbdev->indicator = get_indicator(ldq_p(&fib.aibv), len);

    ret = map_indicator(&pbdev->routes.adapter, pbdev->summary_ind);
    if (ret) {
        goto out;
    }

    ret = map_indicator(&pbdev->routes.adapter, pbdev->indicator);
    if (ret) {
        goto out;
    }

    pbdev->routes.adapter.summary_addr = ldq_p(&fib.aisb);
    pbdev->routes.adapter.summary_offset = FIB_DATA_AISBO(ldl_p(&fib.data));
    pbdev->routes.adapter.ind_addr = ldq_p(&fib.aibv);
    pbdev->routes.adapter.ind_offset = FIB_DATA_AIBVO(ldl_p(&fib.data));
    pbdev->isc = isc;
    pbdev->noi = FIB_DATA_NOI(ldl_p(&fib.data));
    pbdev->sum = FIB_DATA_SUM(ldl_p(&fib.data));

    DPRINTF("reg_irqs adapter id %d\n", pbdev->routes.adapter.adapter_id);
    return 0;
out:
    release_indicator(&pbdev->routes.adapter, pbdev->summary_ind);
    release_indicator(&pbdev->routes.adapter, pbdev->indicator);
    pbdev->summary_ind = NULL;
    pbdev->indicator = NULL;
    return ret;
}

int pci_dereg_irqs(S390PCIBusDevice *pbdev)
{
    release_indicator(&pbdev->routes.adapter, pbdev->summary_ind);
    release_indicator(&pbdev->routes.adapter, pbdev->indicator);

    pbdev->summary_ind = NULL;
    pbdev->indicator = NULL;
    pbdev->routes.adapter.summary_addr = 0;
    pbdev->routes.adapter.summary_offset = 0;
    pbdev->routes.adapter.ind_addr = 0;
    pbdev->routes.adapter.ind_offset = 0;
    pbdev->isc = 0;
    pbdev->noi = 0;
    pbdev->sum = 0;

    DPRINTF("dereg_irqs adapter id %d\n", pbdev->routes.adapter.adapter_id);
    return 0;
}

static int reg_ioat(CPUS390XState *env, S390PCIIOMMU *iommu, ZpciFib fib,
                    uintptr_t ra)
{
    uint64_t pba = ldq_p(&fib.pba);
    uint64_t pal = ldq_p(&fib.pal);
    uint64_t g_iota = ldq_p(&fib.iota);
    uint8_t dt = (g_iota >> 2) & 0x7;
    uint8_t t = (g_iota >> 11) & 0x1;

    pba &= ~0xfff;
    pal |= 0xfff;
    if (pba > pal || pba < ZPCI_SDMA_ADDR || pal > ZPCI_EDMA_ADDR) {
        s390_program_interrupt(env, PGM_OPERAND, ra);
        return -EINVAL;
    }

    /* currently we only support designation type 1 with translation */
    if (!(dt == ZPCI_IOTA_RTTO && t)) {
        error_report("unsupported ioat dt %d t %d", dt, t);
        s390_program_interrupt(env, PGM_OPERAND, ra);
        return -EINVAL;
    }

    iommu->pba = pba;
    iommu->pal = pal;
    iommu->g_iota = g_iota;

    s390_pci_iommu_enable(iommu);

    return 0;
}

void pci_dereg_ioat(S390PCIIOMMU *iommu)
{
    s390_pci_iommu_disable(iommu);
    iommu->pba = 0;
    iommu->pal = 0;
    iommu->g_iota = 0;
}

void fmb_timer_free(S390PCIBusDevice *pbdev)
{
    if (pbdev->fmb_timer) {
        timer_free(pbdev->fmb_timer);
        pbdev->fmb_timer = NULL;
    }
    pbdev->fmb_addr = 0;
    memset(&pbdev->fmb, 0, sizeof(ZpciFmb));
}

static int fmb_do_update(S390PCIBusDevice *pbdev, int offset, uint64_t val,
                         int len)
{
    MemTxResult ret;
    uint64_t dst = pbdev->fmb_addr + offset;

    switch (len) {
    case 8:
        address_space_stq_be(&address_space_memory, dst, val,
                             MEMTXATTRS_UNSPECIFIED,
                             &ret);
        break;
    case 4:
        address_space_stl_be(&address_space_memory, dst, val,
                             MEMTXATTRS_UNSPECIFIED,
                             &ret);
        break;
    case 2:
        address_space_stw_be(&address_space_memory, dst, val,
                             MEMTXATTRS_UNSPECIFIED,
                             &ret);
        break;
    case 1:
        address_space_stb(&address_space_memory, dst, val,
                          MEMTXATTRS_UNSPECIFIED,
                          &ret);
        break;
    default:
        ret = MEMTX_ERROR;
        break;
    }
    if (ret != MEMTX_OK) {
        s390_pci_generate_error_event(ERR_EVENT_FMBA, pbdev->fh, pbdev->fid,
                                      pbdev->fmb_addr, 0);
        fmb_timer_free(pbdev);
    }

    return ret;
}

static void fmb_update(void *opaque)
{
    S390PCIBusDevice *pbdev = opaque;
    int64_t t = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
    int i;

    /* Update U bit */
    pbdev->fmb.last_update *= 2;
    pbdev->fmb.last_update |= UPDATE_U_BIT;
    if (fmb_do_update(pbdev, offsetof(ZpciFmb, last_update),
                      pbdev->fmb.last_update,
                      sizeof(pbdev->fmb.last_update))) {
        return;
    }

    /* Update FMB sample count */
    if (fmb_do_update(pbdev, offsetof(ZpciFmb, sample),
                      pbdev->fmb.sample++,
                      sizeof(pbdev->fmb.sample))) {
        return;
    }

    /* Update FMB counters */
    for (i = 0; i < ZPCI_FMB_CNT_MAX; i++) {
        if (fmb_do_update(pbdev, offsetof(ZpciFmb, counter[i]),
                          pbdev->fmb.counter[i],
                          sizeof(pbdev->fmb.counter[0]))) {
            return;
        }
    }

    /* Clear U bit and update the time */
    pbdev->fmb.last_update = time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
    pbdev->fmb.last_update *= 2;
    if (fmb_do_update(pbdev, offsetof(ZpciFmb, last_update),
                      pbdev->fmb.last_update,
                      sizeof(pbdev->fmb.last_update))) {
        return;
    }
    timer_mod(pbdev->fmb_timer, t + DEFAULT_MUI);
}

int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
                        uintptr_t ra)
{
    CPUS390XState *env = &cpu->env;
    uint8_t oc, dmaas;
    uint32_t fh;
    ZpciFib fib;
    S390PCIBusDevice *pbdev;
    uint64_t cc = ZPCI_PCI_LS_OK;

    if (env->psw.mask & PSW_MASK_PSTATE) {
        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
        return 0;
    }

    oc = env->regs[r1] & 0xff;
    dmaas = (env->regs[r1] >> 16) & 0xff;
    fh = env->regs[r1] >> 32;

    if (fiba & 0x7) {
        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
        return 0;
    }

    pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
    if (!pbdev) {
        DPRINTF("mpcifc no pci dev fh 0x%x\n", fh);
        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
        return 0;
    }

    switch (pbdev->state) {
    case ZPCI_FS_RESERVED:
    case ZPCI_FS_STANDBY:
    case ZPCI_FS_DISABLED:
    case ZPCI_FS_PERMANENT_ERROR:
        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
        return 0;
    default:
        break;
    }

    if (s390_cpu_virt_mem_read(cpu, fiba, ar, (uint8_t *)&fib, sizeof(fib))) {
        s390_cpu_virt_mem_handle_exc(cpu, ra);
        return 0;
    }

    if (fib.fmt != 0) {
        s390_program_interrupt(env, PGM_OPERAND, ra);
        return 0;
    }

    switch (oc) {
    case ZPCI_MOD_FC_REG_INT:
        if (pbdev->summary_ind) {
            cc = ZPCI_PCI_LS_ERR;
            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
        } else if (reg_irqs(env, pbdev, fib)) {
            cc = ZPCI_PCI_LS_ERR;
            s390_set_status_code(env, r1, ZPCI_MOD_ST_RES_NOT_AVAIL);
        }
        break;
    case ZPCI_MOD_FC_DEREG_INT:
        if (!pbdev->summary_ind) {
            cc = ZPCI_PCI_LS_ERR;
            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
        } else {
            pci_dereg_irqs(pbdev);
        }
        break;
    case ZPCI_MOD_FC_REG_IOAT:
        if (dmaas != 0) {
            cc = ZPCI_PCI_LS_ERR;
            s390_set_status_code(env, r1, ZPCI_MOD_ST_DMAAS_INVAL);
        } else if (pbdev->iommu->enabled) {
            cc = ZPCI_PCI_LS_ERR;
            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
        } else if (reg_ioat(env, pbdev->iommu, fib, ra)) {
            cc = ZPCI_PCI_LS_ERR;
            s390_set_status_code(env, r1, ZPCI_MOD_ST_INSUF_RES);
        }
        break;
    case ZPCI_MOD_FC_DEREG_IOAT:
        if (dmaas != 0) {
            cc = ZPCI_PCI_LS_ERR;
            s390_set_status_code(env, r1, ZPCI_MOD_ST_DMAAS_INVAL);
        } else if (!pbdev->iommu->enabled) {
            cc = ZPCI_PCI_LS_ERR;
            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
        } else {
            pci_dereg_ioat(pbdev->iommu);
        }
        break;
    case ZPCI_MOD_FC_REREG_IOAT:
        if (dmaas != 0) {
            cc = ZPCI_PCI_LS_ERR;
            s390_set_status_code(env, r1, ZPCI_MOD_ST_DMAAS_INVAL);
        } else if (!pbdev->iommu->enabled) {
            cc = ZPCI_PCI_LS_ERR;
            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
        } else {
            pci_dereg_ioat(pbdev->iommu);
            if (reg_ioat(env, pbdev->iommu, fib, ra)) {
                cc = ZPCI_PCI_LS_ERR;
                s390_set_status_code(env, r1, ZPCI_MOD_ST_INSUF_RES);
            }
        }
        break;
    case ZPCI_MOD_FC_RESET_ERROR:
        switch (pbdev->state) {
        case ZPCI_FS_BLOCKED:
        case ZPCI_FS_ERROR:
            pbdev->state = ZPCI_FS_ENABLED;
            break;
        default:
            cc = ZPCI_PCI_LS_ERR;
            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
        }
        break;
    case ZPCI_MOD_FC_RESET_BLOCK:
        switch (pbdev->state) {
        case ZPCI_FS_ERROR:
            pbdev->state = ZPCI_FS_BLOCKED;
            break;
        default:
            cc = ZPCI_PCI_LS_ERR;
            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
        }
        break;
    case ZPCI_MOD_FC_SET_MEASURE: {
        uint64_t fmb_addr = ldq_p(&fib.fmb_addr);

        if (fmb_addr & FMBK_MASK) {
            cc = ZPCI_PCI_LS_ERR;
            s390_pci_generate_error_event(ERR_EVENT_FMBPRO, pbdev->fh,
                                          pbdev->fid, fmb_addr, 0);
            fmb_timer_free(pbdev);
            break;
        }

        if (!fmb_addr) {
            /* Stop updating FMB. */
            fmb_timer_free(pbdev);
            break;
        }

        if (!pbdev->fmb_timer) {
            pbdev->fmb_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
                                            fmb_update, pbdev);
        } else if (timer_pending(pbdev->fmb_timer)) {
            /* Remove pending timer to update FMB address. */
            timer_del(pbdev->fmb_timer);
        }
        pbdev->fmb_addr = fmb_addr;
        timer_mod(pbdev->fmb_timer,
                  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + DEFAULT_MUI);
        break;
    }
    default:
        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
        cc = ZPCI_PCI_LS_ERR;
    }

    setcc(cpu, cc);
    return 0;
}

int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
                         uintptr_t ra)
{
    CPUS390XState *env = &cpu->env;
    uint8_t dmaas;
    uint32_t fh;
    ZpciFib fib;
    S390PCIBusDevice *pbdev;
    uint32_t data;
    uint64_t cc = ZPCI_PCI_LS_OK;

    if (env->psw.mask & PSW_MASK_PSTATE) {
        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
        return 0;
    }

    fh = env->regs[r1] >> 32;
    dmaas = (env->regs[r1] >> 16) & 0xff;

    if (dmaas) {
        setcc(cpu, ZPCI_PCI_LS_ERR);
        s390_set_status_code(env, r1, ZPCI_STPCIFC_ST_INVAL_DMAAS);
        return 0;
    }

    if (fiba & 0x7) {
        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
        return 0;
    }

    pbdev = s390_pci_find_dev_by_idx(s390_get_phb(), fh & FH_MASK_INDEX);
    if (!pbdev) {
        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
        return 0;
    }

    memset(&fib, 0, sizeof(fib));

    switch (pbdev->state) {
    case ZPCI_FS_RESERVED:
    case ZPCI_FS_STANDBY:
        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
        return 0;
    case ZPCI_FS_DISABLED:
        if (fh & FH_MASK_ENABLE) {
            setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
            return 0;
        }
        goto out;
    /* BLOCKED bit is set to one coincident with the setting of ERROR bit.
     * FH Enabled bit is set to one in states of ENABLED, BLOCKED or ERROR. */
    case ZPCI_FS_ERROR:
        fib.fc |= 0x20;
        /* fallthrough */
    case ZPCI_FS_BLOCKED:
        fib.fc |= 0x40;
        /* fallthrough */
    case ZPCI_FS_ENABLED:
        fib.fc |= 0x80;
        if (pbdev->iommu->enabled) {
            fib.fc |= 0x10;
        }
        if (!(fh & FH_MASK_ENABLE)) {
            env->regs[r1] |= 1ULL << 63;
        }
        break;
    case ZPCI_FS_PERMANENT_ERROR:
        setcc(cpu, ZPCI_PCI_LS_ERR);
        s390_set_status_code(env, r1, ZPCI_STPCIFC_ST_PERM_ERROR);
        return 0;
    }

    stq_p(&fib.pba, pbdev->iommu->pba);
    stq_p(&fib.pal, pbdev->iommu->pal);
    stq_p(&fib.iota, pbdev->iommu->g_iota);
    stq_p(&fib.aibv, pbdev->routes.adapter.ind_addr);
    stq_p(&fib.aisb, pbdev->routes.adapter.summary_addr);
    stq_p(&fib.fmb_addr, pbdev->fmb_addr);

    data = ((uint32_t)pbdev->isc << 28) | ((uint32_t)pbdev->noi << 16) |
           ((uint32_t)pbdev->routes.adapter.ind_offset << 8) |
           ((uint32_t)pbdev->sum << 7) | pbdev->routes.adapter.summary_offset;
    stl_p(&fib.data, data);

out:
    if (s390_cpu_virt_mem_write(cpu, fiba, ar, (uint8_t *)&fib, sizeof(fib))) {
        s390_cpu_virt_mem_handle_exc(cpu, ra);
        return 0;
    }

    setcc(cpu, cc);
    return 0;
}
