/*
 * 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 "s390-pci-inst.h"
#include "s390-pci-bus.h"
#include "exec/memop.h"
#include "exec/memory-internal.h"
#include "qemu/error-report.h"
#include "sysemu/hw_accel.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 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;
        }

        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]);
        }

        stq_p(&resquery->sdma, ZPCI_SDMA_ADDR);
        stq_p(&resquery->edma, ZPCI_EDMA_ADDR);
        stl_p(&resquery->fid, pbdev->fid);
        stw_p(&resquery->pchid, 0);
        stw_p(&resquery->ug, 1);
        stl_p(&resquery->uid, pbdev->uid);
        stw_p(&resquery->hdr.rsp, CLP_RC_OK);
        break;
    }
    case CLP_QUERY_PCI_FNGRP: {
        ClpRspQueryPciGrp *resgrp = (ClpRspQueryPciGrp *)resh;
        resgrp->fr = 1;
        stq_p(&resgrp->dasm, 0);
        stq_p(&resgrp->msia, ZPCI_MSI_ADDR);
        stw_p(&resgrp->mui, DEFAULT_MUI);
        stw_p(&resgrp->i, 128);
        stw_p(&resgrp->maxstbl, 128);
        resgrp->version = 0;

        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 void s390_pci_update_iotlb(S390PCIIOMMU *iommu, S390IOTLBEntry *entry)
{
    S390IOTLBEntry *cache = g_hash_table_lookup(iommu->iotlb, &entry->iova);
    IOMMUTLBEntry notify = {
        .target_as = &address_space_memory,
        .iova = entry->iova,
        .translated_addr = entry->translated_addr,
        .perm = entry->perm,
        .addr_mask = ~PAGE_MASK,
    };

    if (entry->perm == IOMMU_NONE) {
        if (!cache) {
            return;
        }
        g_hash_table_remove(iommu->iotlb, &entry->iova);
    } else {
        if (cache) {
            if (cache->perm == entry->perm &&
                cache->translated_addr == entry->translated_addr) {
                return;
            }

            notify.perm = IOMMU_NONE;
            memory_region_notify_iommu(&iommu->iommu_mr, 0, notify);
            notify.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);
    }

    memory_region_notify_iommu(&iommu->iommu_mr, 0, notify);
}

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;

    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->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) {
            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]++;
        setcc(cpu, ZPCI_PCI_LS_OK);
    }
    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;
    uint8_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] & 0xff;
    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->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;

    if (!memory_region_access_valid(mr, offset, len, 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_del(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;
}
