int clp_service_call(S390CPU *cpu, uint8_t r2)

{

    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;

    int i;



    cpu_synchronize_state(CPU(cpu));



    if (env->psw.mask & PSW_MASK_PSTATE) {

        program_interrupt(env, PGM_PRIVILEGED, 4);

        return 0;

    }



    if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer, sizeof(*reqh))) {

        return 0;

    }

    reqh = (ClpReqHdr *)buffer;

    req_len = lduw_p(&reqh->len);

    if (req_len < 16 || req_len > 8184 || (req_len % 8 != 0)) {

        program_interrupt(env, PGM_OPERAND, 4);

        return 0;

    }



    if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer,

                               req_len + sizeof(*resh))) {

        return 0;

    }

    resh = (ClpRspHdr *)(buffer + req_len);

    res_len = lduw_p(&resh->len);

    if (res_len < 8 || res_len > 8176 || (res_len % 8 != 0)) {

        program_interrupt(env, PGM_OPERAND, 4);

        return 0;

    }

    if ((req_len + res_len) > 8192) {

        program_interrupt(env, PGM_OPERAND, 4);

        return 0;

    }



    if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer,

                               req_len + res_len)) {

        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(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:

            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:

            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(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->fid);

        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, 0);

        stw_p(&resgrp->i, 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)) {

        return 0;

    }

    setcc(cpu, cc);

    return 0;

}

int clp_service_call(S390CPU *cpu, uint8_t r2)

{

    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;

    int i;



    cpu_synchronize_state(CPU(cpu));



    if (env->psw.mask & PSW_MASK_PSTATE) {

        program_interrupt(env, PGM_PRIVILEGED, 4);

        return 0;

    }



    if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer, sizeof(*reqh))) {

        return 0;

    }

    reqh = (ClpReqHdr *)buffer;

    req_len = lduw_p(&reqh->len);

    if (req_len < 16 || req_len > 8184 || (req_len % 8 != 0)) {

        program_interrupt(env, PGM_OPERAND, 4);

        return 0;

    }



    if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer,

                               req_len + sizeof(*resh))) {

        return 0;

    }

    resh = (ClpRspHdr *)(buffer + req_len);

    res_len = lduw_p(&resh->len);

    if (res_len < 8 || res_len > 8176 || (res_len % 8 != 0)) {

        program_interrupt(env, PGM_OPERAND, 4);

        return 0;

    }

    if ((req_len + res_len) > 8192) {

        program_interrupt(env, PGM_OPERAND, 4);

        return 0;

    }



    if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer,

                               req_len + res_len)) {

        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(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:

            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:

            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(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->fid);

        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, 0);

        stw_p(&resgrp->i, 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)) {

        return 0;

    }

    setcc(cpu, cc);

    return 0;

}

int FUNC_0(S390CPU *VAR_0, uint8_t VAR_1)

{

    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 = &VAR_0->env;

    int VAR_2;



    cpu_synchronize_state(CPU(VAR_0));



    if (env->psw.mask & PSW_MASK_PSTATE) {

        program_interrupt(env, PGM_PRIVILEGED, 4);

        return 0;

    }



    if (s390_cpu_virt_mem_read(VAR_0, env->regs[VAR_1], VAR_1, buffer, sizeof(*reqh))) {

        return 0;

    }

    reqh = (ClpReqHdr *)buffer;

    req_len = lduw_p(&reqh->len);

    if (req_len < 16 || req_len > 8184 || (req_len % 8 != 0)) {

        program_interrupt(env, PGM_OPERAND, 4);

        return 0;

    }



    if (s390_cpu_virt_mem_read(VAR_0, env->regs[VAR_1], VAR_1, buffer,

                               req_len + sizeof(*resh))) {

        return 0;

    }

    resh = (ClpRspHdr *)(buffer + req_len);

    res_len = lduw_p(&resh->len);

    if (res_len < 8 || res_len > 8176 || (res_len % 8 != 0)) {

        program_interrupt(env, PGM_OPERAND, 4);

        return 0;

    }

    if ((req_len + res_len) > 8192) {

        program_interrupt(env, PGM_OPERAND, 4);

        return 0;

    }



    if (s390_cpu_virt_mem_read(VAR_0, env->regs[VAR_1], VAR_1, buffer,

                               req_len + res_len)) {

        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(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:

            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:

            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(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 (VAR_2 = 0; VAR_2 < PCI_BAR_COUNT; VAR_2++) {

            uint32_t data = pci_get_long(pbdev->pdev->config +

                PCI_BASE_ADDRESS_0 + (VAR_2 * 4));



            stl_p(&resquery->bar[VAR_2], data);

            resquery->bar_size[VAR_2] = pbdev->pdev->io_regions[VAR_2].size ?

                                    ctz64(pbdev->pdev->io_regions[VAR_2].size) : 0;

            DPRINTF("bar %d addr 0x%x size 0x%" PRIx64 "barsize 0x%x\n", VAR_2,

                    ldl_p(&resquery->bar[VAR_2]),

                    pbdev->pdev->io_regions[VAR_2].size,

                    resquery->bar_size[VAR_2]);

        }



        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->fid);

        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, 0);

        stw_p(&resgrp->VAR_2, 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(VAR_0, env->regs[VAR_1], VAR_1, buffer,

                                req_len + res_len)) {

        return 0;

    }

    setcc(VAR_0, cc);

    return 0;

}

int FUNC_0(S390CPU *VAR_0, uint8_t VAR_1)
{ 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 = &VAR_0->env; int VAR_2; cpu_synchronize_state(CPU(VAR_0)); if (env->psw.mask & PSW_MASK_PSTATE) { program_interrupt(env, PGM_PRIVILEGED, 4); return 0; } if (s390_cpu_virt_mem_read(VAR_0, env->regs[VAR_1], VAR_1, buffer, sizeof(*reqh))) { return 0; } reqh = (ClpReqHdr *)buffer; req_len = lduw_p(&reqh->len); if (req_len < 16 || req_len > 8184 || (req_len % 8 != 0)) { program_interrupt(env, PGM_OPERAND, 4); return 0; } if (s390_cpu_virt_mem_read(VAR_0, env->regs[VAR_1], VAR_1, buffer,
req_len + sizeof(*resh))) { return 0; } resh = (ClpRspHdr *)(buffer + req_len); res_len = lduw_p(&resh->len); if (res_len < 8 || res_len > 8176 || (res_len % 8 != 0)) { program_interrupt(env, PGM_OPERAND, 4); return 0; } if ((req_len + res_len) > 8192) { program_interrupt(env, PGM_OPERAND, 4); return 0; } if (s390_cpu_virt_mem_read(VAR_0, env->regs[VAR_1], VAR_1, buffer,
req_len + res_len)) { 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(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:
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:
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(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 (VAR_2 = 0; VAR_2 < PCI_BAR_COUNT; VAR_2++) { uint32_t data = pci_get_long(pbdev->pdev->config +
PCI_BASE_ADDRESS_0 + (VAR_2 * 4)); stl_p(&resquery->bar[VAR_2], data); resquery->bar_size[VAR_2] = pbdev->pdev->io_regions[VAR_2].size ?
ctz64(pbdev->pdev->io_regions[VAR_2].size) : 0; DPRINTF("bar %d addr 0x%x size 0x%" PRIx64 "barsize 0x%x\n", VAR_2,
ldl_p(&resquery->bar[VAR_2]),
pbdev->pdev->io_regions[VAR_2].size,
resquery->bar_size[VAR_2]); } 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->fid); 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, 0); stw_p(&resgrp->VAR_2, 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(VAR_0, env->regs[VAR_1], VAR_1, buffer,
req_len + res_len)) { return 0; } setcc(VAR_0, cc); return 0; }