qemu/hw/s390x/s390-pci-bus.c
<<
>>
Prefs
   1/*
   2 * s390 PCI BUS
   3 *
   4 * Copyright 2014 IBM Corp.
   5 * Author(s): Frank Blaschka <frank.blaschka@de.ibm.com>
   6 *            Hong Bo Li <lihbbj@cn.ibm.com>
   7 *            Yi Min Zhao <zyimin@cn.ibm.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2 or (at
  10 * your option) any later version. See the COPYING file in the top-level
  11 * directory.
  12 */
  13
  14#include "qemu/osdep.h"
  15#include "qapi/error.h"
  16#include "qapi/visitor.h"
  17#include "qemu-common.h"
  18#include "cpu.h"
  19#include "s390-pci-bus.h"
  20#include "s390-pci-inst.h"
  21#include "hw/pci/pci_bus.h"
  22#include "hw/pci/msi.h"
  23#include "qemu/error-report.h"
  24
  25/* #define DEBUG_S390PCI_BUS */
  26#ifdef DEBUG_S390PCI_BUS
  27#define DPRINTF(fmt, ...) \
  28    do { fprintf(stderr, "S390pci-bus: " fmt, ## __VA_ARGS__); } while (0)
  29#else
  30#define DPRINTF(fmt, ...) \
  31    do { } while (0)
  32#endif
  33
  34static S390pciState *s390_get_phb(void)
  35{
  36    static S390pciState *phb;
  37
  38    if (!phb) {
  39        phb = S390_PCI_HOST_BRIDGE(
  40            object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
  41        assert(phb != NULL);
  42    }
  43
  44    return phb;
  45}
  46
  47int chsc_sei_nt2_get_event(void *res)
  48{
  49    ChscSeiNt2Res *nt2_res = (ChscSeiNt2Res *)res;
  50    PciCcdfAvail *accdf;
  51    PciCcdfErr *eccdf;
  52    int rc = 1;
  53    SeiContainer *sei_cont;
  54    S390pciState *s = s390_get_phb();
  55
  56    sei_cont = QTAILQ_FIRST(&s->pending_sei);
  57    if (sei_cont) {
  58        QTAILQ_REMOVE(&s->pending_sei, sei_cont, link);
  59        nt2_res->nt = 2;
  60        nt2_res->cc = sei_cont->cc;
  61        nt2_res->length = cpu_to_be16(sizeof(ChscSeiNt2Res));
  62        switch (sei_cont->cc) {
  63        case 1: /* error event */
  64            eccdf = (PciCcdfErr *)nt2_res->ccdf;
  65            eccdf->fid = cpu_to_be32(sei_cont->fid);
  66            eccdf->fh = cpu_to_be32(sei_cont->fh);
  67            eccdf->e = cpu_to_be32(sei_cont->e);
  68            eccdf->faddr = cpu_to_be64(sei_cont->faddr);
  69            eccdf->pec = cpu_to_be16(sei_cont->pec);
  70            break;
  71        case 2: /* availability event */
  72            accdf = (PciCcdfAvail *)nt2_res->ccdf;
  73            accdf->fid = cpu_to_be32(sei_cont->fid);
  74            accdf->fh = cpu_to_be32(sei_cont->fh);
  75            accdf->pec = cpu_to_be16(sei_cont->pec);
  76            break;
  77        default:
  78            abort();
  79        }
  80        g_free(sei_cont);
  81        rc = 0;
  82    }
  83
  84    return rc;
  85}
  86
  87int chsc_sei_nt2_have_event(void)
  88{
  89    S390pciState *s = s390_get_phb();
  90
  91    return !QTAILQ_EMPTY(&s->pending_sei);
  92}
  93
  94S390PCIBusDevice *s390_pci_find_next_avail_dev(S390PCIBusDevice *pbdev)
  95{
  96    int idx = 0;
  97    S390PCIBusDevice *dev = NULL;
  98    S390pciState *s = s390_get_phb();
  99
 100    if (pbdev) {
 101        idx = (pbdev->fh & FH_MASK_INDEX) + 1;
 102    }
 103
 104    for (; idx < PCI_SLOT_MAX; idx++) {
 105        dev = s->pbdev[idx];
 106        if (dev && dev->state != ZPCI_FS_RESERVED) {
 107            return dev;
 108        }
 109    }
 110
 111    return NULL;
 112}
 113
 114S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid)
 115{
 116    S390PCIBusDevice *pbdev;
 117    int i;
 118    S390pciState *s = s390_get_phb();
 119
 120    for (i = 0; i < PCI_SLOT_MAX; i++) {
 121        pbdev = s->pbdev[i];
 122        if (pbdev && pbdev->fid == fid) {
 123            return pbdev;
 124        }
 125    }
 126
 127    return NULL;
 128}
 129
 130void s390_pci_sclp_configure(SCCB *sccb)
 131{
 132    PciCfgSccb *psccb = (PciCfgSccb *)sccb;
 133    S390PCIBusDevice *pbdev = s390_pci_find_dev_by_fid(be32_to_cpu(psccb->aid));
 134    uint16_t rc;
 135
 136    if (be16_to_cpu(sccb->h.length) < 16) {
 137        rc = SCLP_RC_INSUFFICIENT_SCCB_LENGTH;
 138        goto out;
 139    }
 140
 141    if (!pbdev) {
 142        DPRINTF("sclp config no dev found\n");
 143        rc = SCLP_RC_ADAPTER_ID_NOT_RECOGNIZED;
 144        goto out;
 145    }
 146
 147    switch (pbdev->state) {
 148    case ZPCI_FS_RESERVED:
 149        rc = SCLP_RC_ADAPTER_IN_RESERVED_STATE;
 150        break;
 151    case ZPCI_FS_STANDBY:
 152        pbdev->state = ZPCI_FS_DISABLED;
 153        rc = SCLP_RC_NORMAL_COMPLETION;
 154        break;
 155    default:
 156        rc = SCLP_RC_NO_ACTION_REQUIRED;
 157    }
 158out:
 159    psccb->header.response_code = cpu_to_be16(rc);
 160}
 161
 162void s390_pci_sclp_deconfigure(SCCB *sccb)
 163{
 164    PciCfgSccb *psccb = (PciCfgSccb *)sccb;
 165    S390PCIBusDevice *pbdev = s390_pci_find_dev_by_fid(be32_to_cpu(psccb->aid));
 166    uint16_t rc;
 167
 168    if (be16_to_cpu(sccb->h.length) < 16) {
 169        rc = SCLP_RC_INSUFFICIENT_SCCB_LENGTH;
 170        goto out;
 171    }
 172
 173    if (!pbdev) {
 174        DPRINTF("sclp deconfig no dev found\n");
 175        rc = SCLP_RC_ADAPTER_ID_NOT_RECOGNIZED;
 176        goto out;
 177    }
 178
 179    switch (pbdev->state) {
 180    case ZPCI_FS_RESERVED:
 181        rc = SCLP_RC_ADAPTER_IN_RESERVED_STATE;
 182        break;
 183    case ZPCI_FS_STANDBY:
 184        rc = SCLP_RC_NO_ACTION_REQUIRED;
 185        break;
 186    default:
 187        if (pbdev->summary_ind) {
 188            pci_dereg_irqs(pbdev);
 189        }
 190        if (pbdev->iommu_enabled) {
 191            pci_dereg_ioat(pbdev);
 192        }
 193        pbdev->state = ZPCI_FS_STANDBY;
 194        rc = SCLP_RC_NORMAL_COMPLETION;
 195
 196        if (pbdev->release_timer) {
 197            qdev_unplug(DEVICE(pbdev->pdev), NULL);
 198        }
 199    }
 200out:
 201    psccb->header.response_code = cpu_to_be16(rc);
 202}
 203
 204static S390PCIBusDevice *s390_pci_find_dev_by_uid(uint16_t uid)
 205{
 206    int i;
 207    S390PCIBusDevice *pbdev;
 208    S390pciState *s = s390_get_phb();
 209
 210    for (i = 0; i < PCI_SLOT_MAX; i++) {
 211        pbdev = s->pbdev[i];
 212        if (!pbdev) {
 213            continue;
 214        }
 215
 216        if (pbdev->uid == uid) {
 217            return pbdev;
 218        }
 219    }
 220
 221    return NULL;
 222}
 223
 224static S390PCIBusDevice *s390_pci_find_dev_by_target(const char *target)
 225{
 226    int i;
 227    S390PCIBusDevice *pbdev;
 228    S390pciState *s = s390_get_phb();
 229
 230    if (!target) {
 231        return NULL;
 232    }
 233
 234    for (i = 0; i < PCI_SLOT_MAX; i++) {
 235        pbdev = s->pbdev[i];
 236        if (!pbdev) {
 237            continue;
 238        }
 239
 240        if (!strcmp(pbdev->target, target)) {
 241            return pbdev;
 242        }
 243    }
 244
 245    return NULL;
 246}
 247
 248S390PCIBusDevice *s390_pci_find_dev_by_idx(uint32_t idx)
 249{
 250    S390pciState *s = s390_get_phb();
 251
 252    return s->pbdev[idx & FH_MASK_INDEX];
 253}
 254
 255S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh)
 256{
 257    S390pciState *s = s390_get_phb();
 258    S390PCIBusDevice *pbdev;
 259
 260    pbdev = s->pbdev[fh & FH_MASK_INDEX];
 261    if (pbdev && pbdev->fh == fh) {
 262        return pbdev;
 263    }
 264
 265    return NULL;
 266}
 267
 268static void s390_pci_generate_event(uint8_t cc, uint16_t pec, uint32_t fh,
 269                                    uint32_t fid, uint64_t faddr, uint32_t e)
 270{
 271    SeiContainer *sei_cont;
 272    S390pciState *s = s390_get_phb();
 273
 274    sei_cont = g_malloc0(sizeof(SeiContainer));
 275    sei_cont->fh = fh;
 276    sei_cont->fid = fid;
 277    sei_cont->cc = cc;
 278    sei_cont->pec = pec;
 279    sei_cont->faddr = faddr;
 280    sei_cont->e = e;
 281
 282    QTAILQ_INSERT_TAIL(&s->pending_sei, sei_cont, link);
 283    css_generate_css_crws(0);
 284}
 285
 286static void s390_pci_generate_plug_event(uint16_t pec, uint32_t fh,
 287                                         uint32_t fid)
 288{
 289    s390_pci_generate_event(2, pec, fh, fid, 0, 0);
 290}
 291
 292void s390_pci_generate_error_event(uint16_t pec, uint32_t fh, uint32_t fid,
 293                                   uint64_t faddr, uint32_t e)
 294{
 295    s390_pci_generate_event(1, pec, fh, fid, faddr, e);
 296}
 297
 298static void s390_pci_set_irq(void *opaque, int irq, int level)
 299{
 300    /* nothing to do */
 301}
 302
 303static int s390_pci_map_irq(PCIDevice *pci_dev, int irq_num)
 304{
 305    /* nothing to do */
 306    return 0;
 307}
 308
 309static uint64_t s390_pci_get_table_origin(uint64_t iota)
 310{
 311    return iota & ~ZPCI_IOTA_RTTO_FLAG;
 312}
 313
 314static unsigned int calc_rtx(dma_addr_t ptr)
 315{
 316    return ((unsigned long) ptr >> ZPCI_RT_SHIFT) & ZPCI_INDEX_MASK;
 317}
 318
 319static unsigned int calc_sx(dma_addr_t ptr)
 320{
 321    return ((unsigned long) ptr >> ZPCI_ST_SHIFT) & ZPCI_INDEX_MASK;
 322}
 323
 324static unsigned int calc_px(dma_addr_t ptr)
 325{
 326    return ((unsigned long) ptr >> PAGE_SHIFT) & ZPCI_PT_MASK;
 327}
 328
 329static uint64_t get_rt_sto(uint64_t entry)
 330{
 331    return ((entry & ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_RTX)
 332                ? (entry & ZPCI_RTE_ADDR_MASK)
 333                : 0;
 334}
 335
 336static uint64_t get_st_pto(uint64_t entry)
 337{
 338    return ((entry & ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_SX)
 339            ? (entry & ZPCI_STE_ADDR_MASK)
 340            : 0;
 341}
 342
 343static uint64_t s390_guest_io_table_walk(uint64_t guest_iota,
 344                                  uint64_t guest_dma_address)
 345{
 346    uint64_t sto_a, pto_a, px_a;
 347    uint64_t sto, pto, pte;
 348    uint32_t rtx, sx, px;
 349
 350    rtx = calc_rtx(guest_dma_address);
 351    sx = calc_sx(guest_dma_address);
 352    px = calc_px(guest_dma_address);
 353
 354    sto_a = guest_iota + rtx * sizeof(uint64_t);
 355    sto = address_space_ldq(&address_space_memory, sto_a,
 356                            MEMTXATTRS_UNSPECIFIED, NULL);
 357    sto = get_rt_sto(sto);
 358    if (!sto) {
 359        pte = 0;
 360        goto out;
 361    }
 362
 363    pto_a = sto + sx * sizeof(uint64_t);
 364    pto = address_space_ldq(&address_space_memory, pto_a,
 365                            MEMTXATTRS_UNSPECIFIED, NULL);
 366    pto = get_st_pto(pto);
 367    if (!pto) {
 368        pte = 0;
 369        goto out;
 370    }
 371
 372    px_a = pto + px * sizeof(uint64_t);
 373    pte = address_space_ldq(&address_space_memory, px_a,
 374                            MEMTXATTRS_UNSPECIFIED, NULL);
 375
 376out:
 377    return pte;
 378}
 379
 380static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *iommu, hwaddr addr,
 381                                          bool is_write)
 382{
 383    uint64_t pte;
 384    uint32_t flags;
 385    S390PCIBusDevice *pbdev = container_of(iommu, S390PCIBusDevice, iommu_mr);
 386    IOMMUTLBEntry ret = {
 387        .target_as = &address_space_memory,
 388        .iova = 0,
 389        .translated_addr = 0,
 390        .addr_mask = ~(hwaddr)0,
 391        .perm = IOMMU_NONE,
 392    };
 393
 394    switch (pbdev->state) {
 395    case ZPCI_FS_ENABLED:
 396    case ZPCI_FS_BLOCKED:
 397        if (!pbdev->iommu_enabled) {
 398            return ret;
 399        }
 400        break;
 401    default:
 402        return ret;
 403    }
 404
 405    DPRINTF("iommu trans addr 0x%" PRIx64 "\n", addr);
 406
 407    if (addr < pbdev->pba || addr > pbdev->pal) {
 408        return ret;
 409    }
 410
 411    pte = s390_guest_io_table_walk(s390_pci_get_table_origin(pbdev->g_iota),
 412                                   addr);
 413    if (!pte) {
 414        return ret;
 415    }
 416
 417    flags = pte & ZPCI_PTE_FLAG_MASK;
 418    ret.iova = addr;
 419    ret.translated_addr = pte & ZPCI_PTE_ADDR_MASK;
 420    ret.addr_mask = 0xfff;
 421
 422    if (flags & ZPCI_PTE_INVALID) {
 423        ret.perm = IOMMU_NONE;
 424    } else {
 425        ret.perm = IOMMU_RW;
 426    }
 427
 428    return ret;
 429}
 430
 431static const MemoryRegionIOMMUOps s390_iommu_ops = {
 432    .translate = s390_translate_iommu,
 433};
 434
 435static AddressSpace *s390_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
 436{
 437    S390pciState *s = opaque;
 438
 439    return &s->iommu[PCI_SLOT(devfn)]->as;
 440}
 441
 442static uint8_t set_ind_atomic(uint64_t ind_loc, uint8_t to_be_set)
 443{
 444    uint8_t ind_old, ind_new;
 445    hwaddr len = 1;
 446    uint8_t *ind_addr;
 447
 448    ind_addr = cpu_physical_memory_map(ind_loc, &len, 1);
 449    if (!ind_addr) {
 450        s390_pci_generate_error_event(ERR_EVENT_AIRERR, 0, 0, 0, 0);
 451        return -1;
 452    }
 453    do {
 454        ind_old = *ind_addr;
 455        ind_new = ind_old | to_be_set;
 456    } while (atomic_cmpxchg(ind_addr, ind_old, ind_new) != ind_old);
 457    cpu_physical_memory_unmap(ind_addr, len, 1, len);
 458
 459    return ind_old;
 460}
 461
 462static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,
 463                                unsigned int size)
 464{
 465    S390PCIBusDevice *pbdev = opaque;
 466    uint32_t idx = data >> ZPCI_MSI_VEC_BITS;
 467    uint32_t vec = data & ZPCI_MSI_VEC_MASK;
 468    uint64_t ind_bit;
 469    uint32_t sum_bit;
 470    uint32_t e = 0;
 471
 472    DPRINTF("write_msix data 0x%" PRIx64 " idx %d vec 0x%x\n", data, idx, vec);
 473
 474    if (!pbdev) {
 475        e |= (vec << ERR_EVENT_MVN_OFFSET);
 476        s390_pci_generate_error_event(ERR_EVENT_NOMSI, idx, 0, addr, e);
 477        return;
 478    }
 479
 480    if (pbdev->state != ZPCI_FS_ENABLED) {
 481        return;
 482    }
 483
 484    ind_bit = pbdev->routes.adapter.ind_offset;
 485    sum_bit = pbdev->routes.adapter.summary_offset;
 486
 487    set_ind_atomic(pbdev->routes.adapter.ind_addr + (ind_bit + vec) / 8,
 488                   0x80 >> ((ind_bit + vec) % 8));
 489    if (!set_ind_atomic(pbdev->routes.adapter.summary_addr + sum_bit / 8,
 490                                       0x80 >> (sum_bit % 8))) {
 491        css_adapter_interrupt(pbdev->isc);
 492    }
 493}
 494
 495static uint64_t s390_msi_ctrl_read(void *opaque, hwaddr addr, unsigned size)
 496{
 497    return 0xffffffff;
 498}
 499
 500static const MemoryRegionOps s390_msi_ctrl_ops = {
 501    .write = s390_msi_ctrl_write,
 502    .read = s390_msi_ctrl_read,
 503    .endianness = DEVICE_LITTLE_ENDIAN,
 504};
 505
 506void s390_pci_iommu_enable(S390PCIBusDevice *pbdev)
 507{
 508    memory_region_init_iommu(&pbdev->iommu_mr, OBJECT(&pbdev->iommu->mr),
 509                             &s390_iommu_ops, "iommu-s390", pbdev->pal + 1);
 510    memory_region_add_subregion(&pbdev->iommu->mr, 0, &pbdev->iommu_mr);
 511    pbdev->iommu_enabled = true;
 512}
 513
 514void s390_pci_iommu_disable(S390PCIBusDevice *pbdev)
 515{
 516    memory_region_del_subregion(&pbdev->iommu->mr, &pbdev->iommu_mr);
 517    object_unparent(OBJECT(&pbdev->iommu_mr));
 518    pbdev->iommu_enabled = false;
 519}
 520
 521static void s390_pcihost_init_as(S390pciState *s)
 522{
 523    int i;
 524    S390PCIIOMMU *iommu;
 525
 526    for (i = 0; i < PCI_SLOT_MAX; i++) {
 527        iommu = g_malloc0(sizeof(S390PCIIOMMU));
 528        memory_region_init(&iommu->mr, OBJECT(s),
 529                           "iommu-root-s390", UINT64_MAX);
 530        address_space_init(&iommu->as, &iommu->mr, "iommu-pci");
 531
 532        s->iommu[i] = iommu;
 533    }
 534}
 535
 536static int s390_pcihost_init(SysBusDevice *dev)
 537{
 538    PCIBus *b;
 539    BusState *bus;
 540    PCIHostState *phb = PCI_HOST_BRIDGE(dev);
 541    S390pciState *s = S390_PCI_HOST_BRIDGE(dev);
 542
 543    DPRINTF("host_init\n");
 544
 545    b = pci_register_bus(DEVICE(dev), NULL,
 546                         s390_pci_set_irq, s390_pci_map_irq, NULL,
 547                         get_system_memory(), get_system_io(), 0, 64,
 548                         TYPE_PCI_BUS);
 549    s390_pcihost_init_as(s);
 550    pci_setup_iommu(b, s390_pci_dma_iommu, s);
 551
 552    bus = BUS(b);
 553    qbus_set_hotplug_handler(bus, DEVICE(dev), NULL);
 554    phb->bus = b;
 555
 556    s->bus = S390_PCI_BUS(qbus_create(TYPE_S390_PCI_BUS, DEVICE(s), NULL));
 557    qbus_set_hotplug_handler(BUS(s->bus), DEVICE(s), NULL);
 558
 559    QTAILQ_INIT(&s->pending_sei);
 560    return 0;
 561}
 562
 563static int s390_pci_setup_msix(S390PCIBusDevice *pbdev)
 564{
 565    uint8_t pos;
 566    uint16_t ctrl;
 567    uint32_t table, pba;
 568
 569    pos = pci_find_capability(pbdev->pdev, PCI_CAP_ID_MSIX);
 570    if (!pos) {
 571        pbdev->msix.available = false;
 572        return 0;
 573    }
 574
 575    ctrl = pci_host_config_read_common(pbdev->pdev, pos + PCI_MSIX_FLAGS,
 576             pci_config_size(pbdev->pdev), sizeof(ctrl));
 577    table = pci_host_config_read_common(pbdev->pdev, pos + PCI_MSIX_TABLE,
 578             pci_config_size(pbdev->pdev), sizeof(table));
 579    pba = pci_host_config_read_common(pbdev->pdev, pos + PCI_MSIX_PBA,
 580             pci_config_size(pbdev->pdev), sizeof(pba));
 581
 582    pbdev->msix.table_bar = table & PCI_MSIX_FLAGS_BIRMASK;
 583    pbdev->msix.table_offset = table & ~PCI_MSIX_FLAGS_BIRMASK;
 584    pbdev->msix.pba_bar = pba & PCI_MSIX_FLAGS_BIRMASK;
 585    pbdev->msix.pba_offset = pba & ~PCI_MSIX_FLAGS_BIRMASK;
 586    pbdev->msix.entries = (ctrl & PCI_MSIX_FLAGS_QSIZE) + 1;
 587    pbdev->msix.available = true;
 588    return 0;
 589}
 590
 591static void s390_pci_msix_init(S390PCIBusDevice *pbdev)
 592{
 593    char *name;
 594
 595    name = g_strdup_printf("msix-s390-%04x", pbdev->uid);
 596
 597    memory_region_init_io(&pbdev->msix_notify_mr, OBJECT(pbdev),
 598                          &s390_msi_ctrl_ops, pbdev, name, PAGE_SIZE);
 599    memory_region_add_subregion(&pbdev->iommu->mr, ZPCI_MSI_ADDR,
 600                                &pbdev->msix_notify_mr);
 601
 602    g_free(name);
 603}
 604
 605static void s390_pci_msix_free(S390PCIBusDevice *pbdev)
 606{
 607    memory_region_del_subregion(&pbdev->iommu->mr, &pbdev->msix_notify_mr);
 608    object_unparent(OBJECT(&pbdev->msix_notify_mr));
 609}
 610
 611static S390PCIBusDevice *s390_pci_device_new(const char *target)
 612{
 613    DeviceState *dev = NULL;
 614    S390pciState *s = s390_get_phb();
 615
 616    dev = qdev_try_create(BUS(s->bus), TYPE_S390_PCI_DEVICE);
 617    if (!dev) {
 618        return NULL;
 619    }
 620
 621    qdev_prop_set_string(dev, "target", target);
 622    qdev_init_nofail(dev);
 623
 624    return S390_PCI_DEVICE(dev);
 625}
 626
 627static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
 628                                  DeviceState *dev, Error **errp)
 629{
 630    PCIDevice *pdev = NULL;
 631    S390PCIBusDevice *pbdev = NULL;
 632    S390pciState *s = s390_get_phb();
 633
 634    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
 635        pdev = PCI_DEVICE(dev);
 636
 637        if (!dev->id) {
 638            /* In the case the PCI device does not define an id */
 639            /* we generate one based on the PCI address         */
 640            dev->id = g_strdup_printf("auto_%02x:%02x.%01x",
 641                                      pci_bus_num(pdev->bus),
 642                                      PCI_SLOT(pdev->devfn),
 643                                      PCI_FUNC(pdev->devfn));
 644        }
 645
 646        pbdev = s390_pci_find_dev_by_target(dev->id);
 647        if (!pbdev) {
 648            pbdev = s390_pci_device_new(dev->id);
 649            if (!pbdev) {
 650                error_setg(errp, "create zpci device failed");
 651                return;
 652            }
 653        }
 654
 655        if (object_dynamic_cast(OBJECT(dev), "vfio-pci")) {
 656            pbdev->fh |= FH_SHM_VFIO;
 657        } else {
 658            pbdev->fh |= FH_SHM_EMUL;
 659        }
 660
 661        pbdev->pdev = pdev;
 662        pbdev->iommu = s->iommu[PCI_SLOT(pdev->devfn)];
 663        pbdev->state = ZPCI_FS_STANDBY;
 664
 665        s390_pci_msix_init(pbdev);
 666        s390_pci_setup_msix(pbdev);
 667
 668        if (dev->hotplugged) {
 669            s390_pci_generate_plug_event(HP_EVENT_RESERVED_TO_STANDBY,
 670                                         pbdev->fh, pbdev->fid);
 671        }
 672    } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
 673        int idx;
 674
 675        pbdev = S390_PCI_DEVICE(dev);
 676        for (idx = 0; idx < PCI_SLOT_MAX; idx++) {
 677            if (!s->pbdev[idx]) {
 678                s->pbdev[idx] = pbdev;
 679                pbdev->fh = idx;
 680                return;
 681            }
 682        }
 683
 684        error_setg(errp, "no slot for plugging zpci device");
 685    }
 686}
 687
 688static void s390_pcihost_timer_cb(void *opaque)
 689{
 690    S390PCIBusDevice *pbdev = opaque;
 691
 692    if (pbdev->summary_ind) {
 693        pci_dereg_irqs(pbdev);
 694    }
 695    if (pbdev->iommu_enabled) {
 696        pci_dereg_ioat(pbdev);
 697    }
 698
 699    pbdev->state = ZPCI_FS_STANDBY;
 700    s390_pci_generate_plug_event(HP_EVENT_CONFIGURED_TO_STBRES,
 701                                 pbdev->fh, pbdev->fid);
 702    qdev_unplug(DEVICE(pbdev), NULL);
 703}
 704
 705static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
 706                                    DeviceState *dev, Error **errp)
 707{
 708    int i;
 709    PCIDevice *pci_dev = NULL;
 710    S390PCIBusDevice *pbdev = NULL;
 711    S390pciState *s = s390_get_phb();
 712
 713    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
 714        pci_dev = PCI_DEVICE(dev);
 715
 716        for (i = 0 ; i < PCI_SLOT_MAX; i++) {
 717            if (s->pbdev[i] && s->pbdev[i]->pdev == pci_dev) {
 718                pbdev = s->pbdev[i];
 719                break;
 720            }
 721        }
 722        assert(pbdev != NULL);
 723    } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
 724        pbdev = S390_PCI_DEVICE(dev);
 725        pci_dev = pbdev->pdev;
 726    }
 727
 728    switch (pbdev->state) {
 729    case ZPCI_FS_RESERVED:
 730        goto out;
 731    case ZPCI_FS_STANDBY:
 732        break;
 733    default:
 734        s390_pci_generate_plug_event(HP_EVENT_DECONFIGURE_REQUEST,
 735                                     pbdev->fh, pbdev->fid);
 736        pbdev->release_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
 737                                            s390_pcihost_timer_cb,
 738                                            pbdev);
 739        timer_mod(pbdev->release_timer,
 740                  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + HOT_UNPLUG_TIMEOUT);
 741        return;
 742    }
 743
 744    if (pbdev->release_timer && timer_pending(pbdev->release_timer)) {
 745        timer_del(pbdev->release_timer);
 746        timer_free(pbdev->release_timer);
 747        pbdev->release_timer = NULL;
 748    }
 749
 750    s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,
 751                                 pbdev->fh, pbdev->fid);
 752    object_unparent(OBJECT(pci_dev));
 753    s390_pci_msix_free(pbdev);
 754    pbdev->pdev = NULL;
 755    pbdev->state = ZPCI_FS_RESERVED;
 756out:
 757    pbdev->fid = 0;
 758    s->pbdev[pbdev->fh & FH_MASK_INDEX] = NULL;
 759    object_unparent(OBJECT(pbdev));
 760}
 761
 762static void s390_pcihost_class_init(ObjectClass *klass, void *data)
 763{
 764    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 765    DeviceClass *dc = DEVICE_CLASS(klass);
 766    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
 767
 768    dc->cannot_instantiate_with_device_add_yet = true;
 769    k->init = s390_pcihost_init;
 770    hc->plug = s390_pcihost_hot_plug;
 771    hc->unplug = s390_pcihost_hot_unplug;
 772    msi_nonbroken = true;
 773}
 774
 775static const TypeInfo s390_pcihost_info = {
 776    .name          = TYPE_S390_PCI_HOST_BRIDGE,
 777    .parent        = TYPE_PCI_HOST_BRIDGE,
 778    .instance_size = sizeof(S390pciState),
 779    .class_init    = s390_pcihost_class_init,
 780    .interfaces = (InterfaceInfo[]) {
 781        { TYPE_HOTPLUG_HANDLER },
 782        { }
 783    }
 784};
 785
 786static const TypeInfo s390_pcibus_info = {
 787    .name = TYPE_S390_PCI_BUS,
 788    .parent = TYPE_BUS,
 789    .instance_size = sizeof(S390PCIBus),
 790};
 791
 792static uint16_t s390_pci_generate_uid(void)
 793{
 794    uint16_t uid = 0;
 795
 796    do {
 797        uid++;
 798        if (!s390_pci_find_dev_by_uid(uid)) {
 799            return uid;
 800        }
 801    } while (uid < ZPCI_MAX_UID);
 802
 803    return UID_UNDEFINED;
 804}
 805
 806static uint32_t s390_pci_generate_fid(Error **errp)
 807{
 808    uint32_t fid = 0;
 809
 810    do {
 811        if (!s390_pci_find_dev_by_fid(fid)) {
 812            return fid;
 813        }
 814    } while (fid++ != ZPCI_MAX_FID);
 815
 816    error_setg(errp, "no free fid could be found");
 817    return 0;
 818}
 819
 820static void s390_pci_device_realize(DeviceState *dev, Error **errp)
 821{
 822    S390PCIBusDevice *zpci = S390_PCI_DEVICE(dev);
 823
 824    if (!zpci->target) {
 825        error_setg(errp, "target must be defined");
 826        return;
 827    }
 828
 829    if (s390_pci_find_dev_by_target(zpci->target)) {
 830        error_setg(errp, "target %s already has an associated zpci device",
 831                   zpci->target);
 832        return;
 833    }
 834
 835    if (zpci->uid == UID_UNDEFINED) {
 836        zpci->uid = s390_pci_generate_uid();
 837        if (!zpci->uid) {
 838            error_setg(errp, "no free uid could be found");
 839            return;
 840        }
 841    } else if (s390_pci_find_dev_by_uid(zpci->uid)) {
 842        error_setg(errp, "uid %u already in use", zpci->uid);
 843        return;
 844    }
 845
 846    if (!zpci->fid_defined) {
 847        Error *local_error = NULL;
 848
 849        zpci->fid = s390_pci_generate_fid(&local_error);
 850        if (local_error) {
 851            error_propagate(errp, local_error);
 852            return;
 853        }
 854    } else if (s390_pci_find_dev_by_fid(zpci->fid)) {
 855        error_setg(errp, "fid %u already in use", zpci->fid);
 856        return;
 857    }
 858
 859    zpci->state = ZPCI_FS_RESERVED;
 860}
 861
 862static void s390_pci_device_reset(DeviceState *dev)
 863{
 864    S390PCIBusDevice *pbdev = S390_PCI_DEVICE(dev);
 865
 866    switch (pbdev->state) {
 867    case ZPCI_FS_RESERVED:
 868        return;
 869    case ZPCI_FS_STANDBY:
 870        break;
 871    default:
 872        pbdev->fh &= ~FH_MASK_ENABLE;
 873        pbdev->state = ZPCI_FS_DISABLED;
 874        break;
 875    }
 876
 877    if (pbdev->summary_ind) {
 878        pci_dereg_irqs(pbdev);
 879    }
 880    if (pbdev->iommu_enabled) {
 881        pci_dereg_ioat(pbdev);
 882    }
 883
 884    pbdev->fmb_addr = 0;
 885}
 886
 887static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
 888                         void *opaque, Error **errp)
 889{
 890    Property *prop = opaque;
 891    uint32_t *ptr = qdev_get_prop_ptr(DEVICE(obj), prop);
 892
 893    visit_type_uint32(v, name, ptr, errp);
 894}
 895
 896static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
 897                         void *opaque, Error **errp)
 898{
 899    DeviceState *dev = DEVICE(obj);
 900    S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
 901    Property *prop = opaque;
 902    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
 903
 904    if (dev->realized) {
 905        qdev_prop_set_after_realize(dev, name, errp);
 906        return;
 907    }
 908
 909    visit_type_uint32(v, name, ptr, errp);
 910    zpci->fid_defined = true;
 911}
 912
 913static PropertyInfo s390_pci_fid_propinfo = {
 914    .name = "zpci_fid",
 915    .get = s390_pci_get_fid,
 916    .set = s390_pci_set_fid,
 917};
 918
 919#define DEFINE_PROP_S390_PCI_FID(_n, _s, _f) \
 920    DEFINE_PROP(_n, _s, _f, s390_pci_fid_propinfo, uint32_t)
 921
 922static Property s390_pci_device_properties[] = {
 923    DEFINE_PROP_UINT16("uid", S390PCIBusDevice, uid, UID_UNDEFINED),
 924    DEFINE_PROP_S390_PCI_FID("fid", S390PCIBusDevice, fid),
 925    DEFINE_PROP_STRING("target", S390PCIBusDevice, target),
 926    DEFINE_PROP_END_OF_LIST(),
 927};
 928
 929static void s390_pci_device_class_init(ObjectClass *klass, void *data)
 930{
 931    DeviceClass *dc = DEVICE_CLASS(klass);
 932
 933    dc->desc = "zpci device";
 934    dc->reset = s390_pci_device_reset;
 935    dc->bus_type = TYPE_S390_PCI_BUS;
 936    dc->realize = s390_pci_device_realize;
 937    dc->props = s390_pci_device_properties;
 938}
 939
 940static const TypeInfo s390_pci_device_info = {
 941    .name = TYPE_S390_PCI_DEVICE,
 942    .parent = TYPE_DEVICE,
 943    .instance_size = sizeof(S390PCIBusDevice),
 944    .class_init = s390_pci_device_class_init,
 945};
 946
 947static void s390_pci_register_types(void)
 948{
 949    type_register_static(&s390_pcihost_info);
 950    type_register_static(&s390_pcibus_info);
 951    type_register_static(&s390_pci_device_info);
 952}
 953
 954type_init(s390_pci_register_types)
 955