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    S390pciState *s;
 387    IOMMUTLBEntry ret = {
 388        .target_as = &address_space_memory,
 389        .iova = 0,
 390        .translated_addr = 0,
 391        .addr_mask = ~(hwaddr)0,
 392        .perm = IOMMU_NONE,
 393    };
 394
 395    switch (pbdev->state) {
 396    case ZPCI_FS_ENABLED:
 397    case ZPCI_FS_BLOCKED:
 398        if (!pbdev->iommu_enabled) {
 399            return ret;
 400        }
 401        break;
 402    default:
 403        return ret;
 404    }
 405
 406    DPRINTF("iommu trans addr 0x%" PRIx64 "\n", addr);
 407
 408    s = S390_PCI_HOST_BRIDGE(pci_device_root_bus(pbdev->pdev)->qbus.parent);
 409    /* s390 does not have an APIC mapped to main storage so we use
 410     * a separate AddressSpace only for msix notifications
 411     */
 412    if (addr == ZPCI_MSI_ADDR) {
 413        ret.target_as = &s->msix_notify_as;
 414        ret.iova = addr;
 415        ret.translated_addr = addr;
 416        ret.addr_mask = 0xfff;
 417        ret.perm = IOMMU_RW;
 418        return ret;
 419    }
 420
 421    if (addr < pbdev->pba || addr > pbdev->pal) {
 422        return ret;
 423    }
 424
 425    pte = s390_guest_io_table_walk(s390_pci_get_table_origin(pbdev->g_iota),
 426                                   addr);
 427    if (!pte) {
 428        return ret;
 429    }
 430
 431    flags = pte & ZPCI_PTE_FLAG_MASK;
 432    ret.iova = addr;
 433    ret.translated_addr = pte & ZPCI_PTE_ADDR_MASK;
 434    ret.addr_mask = 0xfff;
 435
 436    if (flags & ZPCI_PTE_INVALID) {
 437        ret.perm = IOMMU_NONE;
 438    } else {
 439        ret.perm = IOMMU_RW;
 440    }
 441
 442    return ret;
 443}
 444
 445static const MemoryRegionIOMMUOps s390_iommu_ops = {
 446    .translate = s390_translate_iommu,
 447};
 448
 449static AddressSpace *s390_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
 450{
 451    S390pciState *s = opaque;
 452
 453    return &s->iommu[PCI_SLOT(devfn)]->as;
 454}
 455
 456static uint8_t set_ind_atomic(uint64_t ind_loc, uint8_t to_be_set)
 457{
 458    uint8_t ind_old, ind_new;
 459    hwaddr len = 1;
 460    uint8_t *ind_addr;
 461
 462    ind_addr = cpu_physical_memory_map(ind_loc, &len, 1);
 463    if (!ind_addr) {
 464        s390_pci_generate_error_event(ERR_EVENT_AIRERR, 0, 0, 0, 0);
 465        return -1;
 466    }
 467    do {
 468        ind_old = *ind_addr;
 469        ind_new = ind_old | to_be_set;
 470    } while (atomic_cmpxchg(ind_addr, ind_old, ind_new) != ind_old);
 471    cpu_physical_memory_unmap(ind_addr, len, 1, len);
 472
 473    return ind_old;
 474}
 475
 476static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,
 477                                unsigned int size)
 478{
 479    S390PCIBusDevice *pbdev;
 480    uint32_t io_int_word;
 481    uint32_t idx = data >> ZPCI_MSI_VEC_BITS;
 482    uint32_t vec = data & ZPCI_MSI_VEC_MASK;
 483    uint64_t ind_bit;
 484    uint32_t sum_bit;
 485    uint32_t e = 0;
 486
 487    DPRINTF("write_msix data 0x%" PRIx64 " idx %d vec 0x%x\n", data, idx, vec);
 488
 489    pbdev = s390_pci_find_dev_by_idx(idx);
 490    if (!pbdev) {
 491        e |= (vec << ERR_EVENT_MVN_OFFSET);
 492        s390_pci_generate_error_event(ERR_EVENT_NOMSI, idx, 0, addr, e);
 493        return;
 494    }
 495
 496    if (pbdev->state != ZPCI_FS_ENABLED) {
 497        return;
 498    }
 499
 500    ind_bit = pbdev->routes.adapter.ind_offset;
 501    sum_bit = pbdev->routes.adapter.summary_offset;
 502
 503    set_ind_atomic(pbdev->routes.adapter.ind_addr + (ind_bit + vec) / 8,
 504                   0x80 >> ((ind_bit + vec) % 8));
 505    if (!set_ind_atomic(pbdev->routes.adapter.summary_addr + sum_bit / 8,
 506                                       0x80 >> (sum_bit % 8))) {
 507        io_int_word = (pbdev->isc << 27) | IO_INT_WORD_AI;
 508        s390_io_interrupt(0, 0, 0, io_int_word);
 509    }
 510}
 511
 512static uint64_t s390_msi_ctrl_read(void *opaque, hwaddr addr, unsigned size)
 513{
 514    return 0xffffffff;
 515}
 516
 517static const MemoryRegionOps s390_msi_ctrl_ops = {
 518    .write = s390_msi_ctrl_write,
 519    .read = s390_msi_ctrl_read,
 520    .endianness = DEVICE_LITTLE_ENDIAN,
 521};
 522
 523void s390_pci_iommu_enable(S390PCIBusDevice *pbdev)
 524{
 525    memory_region_init_iommu(&pbdev->iommu_mr, OBJECT(&pbdev->iommu->mr),
 526                             &s390_iommu_ops, "iommu-s390", pbdev->pal + 1);
 527    memory_region_add_subregion(&pbdev->iommu->mr, 0, &pbdev->iommu_mr);
 528    pbdev->iommu_enabled = true;
 529}
 530
 531void s390_pci_iommu_disable(S390PCIBusDevice *pbdev)
 532{
 533    memory_region_del_subregion(&pbdev->iommu->mr, &pbdev->iommu_mr);
 534    object_unparent(OBJECT(&pbdev->iommu_mr));
 535    pbdev->iommu_enabled = false;
 536}
 537
 538static void s390_pcihost_init_as(S390pciState *s)
 539{
 540    int i;
 541    S390PCIIOMMU *iommu;
 542
 543    for (i = 0; i < PCI_SLOT_MAX; i++) {
 544        iommu = g_malloc0(sizeof(S390PCIIOMMU));
 545        memory_region_init(&iommu->mr, OBJECT(s),
 546                           "iommu-root-s390", UINT64_MAX);
 547        address_space_init(&iommu->as, &iommu->mr, "iommu-pci");
 548
 549        s->iommu[i] = iommu;
 550    }
 551
 552    memory_region_init_io(&s->msix_notify_mr, OBJECT(s),
 553                          &s390_msi_ctrl_ops, s, "msix-s390", UINT64_MAX);
 554    address_space_init(&s->msix_notify_as, &s->msix_notify_mr, "msix-pci");
 555}
 556
 557static int s390_pcihost_init(SysBusDevice *dev)
 558{
 559    PCIBus *b;
 560    BusState *bus;
 561    PCIHostState *phb = PCI_HOST_BRIDGE(dev);
 562    S390pciState *s = S390_PCI_HOST_BRIDGE(dev);
 563
 564    DPRINTF("host_init\n");
 565
 566    b = pci_register_bus(DEVICE(dev), NULL,
 567                         s390_pci_set_irq, s390_pci_map_irq, NULL,
 568                         get_system_memory(), get_system_io(), 0, 64,
 569                         TYPE_PCI_BUS);
 570    s390_pcihost_init_as(s);
 571    pci_setup_iommu(b, s390_pci_dma_iommu, s);
 572
 573    bus = BUS(b);
 574    qbus_set_hotplug_handler(bus, DEVICE(dev), NULL);
 575    phb->bus = b;
 576
 577    s->bus = S390_PCI_BUS(qbus_create(TYPE_S390_PCI_BUS, DEVICE(s), NULL));
 578    qbus_set_hotplug_handler(BUS(s->bus), DEVICE(s), NULL);
 579
 580    QTAILQ_INIT(&s->pending_sei);
 581    return 0;
 582}
 583
 584static int s390_pcihost_setup_msix(S390PCIBusDevice *pbdev)
 585{
 586    uint8_t pos;
 587    uint16_t ctrl;
 588    uint32_t table, pba;
 589
 590    pos = pci_find_capability(pbdev->pdev, PCI_CAP_ID_MSIX);
 591    if (!pos) {
 592        pbdev->msix.available = false;
 593        return 0;
 594    }
 595
 596    ctrl = pci_host_config_read_common(pbdev->pdev, pos + PCI_MSIX_FLAGS,
 597             pci_config_size(pbdev->pdev), sizeof(ctrl));
 598    table = pci_host_config_read_common(pbdev->pdev, pos + PCI_MSIX_TABLE,
 599             pci_config_size(pbdev->pdev), sizeof(table));
 600    pba = pci_host_config_read_common(pbdev->pdev, pos + PCI_MSIX_PBA,
 601             pci_config_size(pbdev->pdev), sizeof(pba));
 602
 603    pbdev->msix.table_bar = table & PCI_MSIX_FLAGS_BIRMASK;
 604    pbdev->msix.table_offset = table & ~PCI_MSIX_FLAGS_BIRMASK;
 605    pbdev->msix.pba_bar = pba & PCI_MSIX_FLAGS_BIRMASK;
 606    pbdev->msix.pba_offset = pba & ~PCI_MSIX_FLAGS_BIRMASK;
 607    pbdev->msix.entries = (ctrl & PCI_MSIX_FLAGS_QSIZE) + 1;
 608    pbdev->msix.available = true;
 609    return 0;
 610}
 611
 612static S390PCIBusDevice *s390_pci_device_new(const char *target)
 613{
 614    DeviceState *dev = NULL;
 615    S390pciState *s = s390_get_phb();
 616
 617    dev = qdev_try_create(BUS(s->bus), TYPE_S390_PCI_DEVICE);
 618    if (!dev) {
 619        return NULL;
 620    }
 621
 622    qdev_prop_set_string(dev, "target", target);
 623    qdev_init_nofail(dev);
 624
 625    return S390_PCI_DEVICE(dev);
 626}
 627
 628static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
 629                                  DeviceState *dev, Error **errp)
 630{
 631    PCIDevice *pdev = NULL;
 632    S390PCIBusDevice *pbdev = NULL;
 633    S390pciState *s = s390_get_phb();
 634
 635    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
 636        pdev = PCI_DEVICE(dev);
 637
 638        if (!dev->id) {
 639            /* In the case the PCI device does not define an id */
 640            /* we generate one based on the PCI address         */
 641            dev->id = g_strdup_printf("auto_%02x:%02x.%01x",
 642                                      pci_bus_num(pdev->bus),
 643                                      PCI_SLOT(pdev->devfn),
 644                                      PCI_FUNC(pdev->devfn));
 645        }
 646
 647        pbdev = s390_pci_find_dev_by_target(dev->id);
 648        if (!pbdev) {
 649            pbdev = s390_pci_device_new(dev->id);
 650            if (!pbdev) {
 651                error_setg(errp, "create zpci device failed");
 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        s390_pcihost_setup_msix(pbdev);
 665
 666        if (dev->hotplugged) {
 667            s390_pci_generate_plug_event(HP_EVENT_RESERVED_TO_STANDBY,
 668                                         pbdev->fh, pbdev->fid);
 669        }
 670    } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
 671        int idx;
 672
 673        pbdev = S390_PCI_DEVICE(dev);
 674        for (idx = 0; idx < PCI_SLOT_MAX; idx++) {
 675            if (!s->pbdev[idx]) {
 676                s->pbdev[idx] = pbdev;
 677                pbdev->fh = idx;
 678                return;
 679            }
 680        }
 681
 682        error_setg(errp, "no slot for plugging zpci device");
 683    }
 684}
 685
 686static void s390_pcihost_timer_cb(void *opaque)
 687{
 688    S390PCIBusDevice *pbdev = opaque;
 689
 690    if (pbdev->summary_ind) {
 691        pci_dereg_irqs(pbdev);
 692    }
 693    if (pbdev->iommu_enabled) {
 694        pci_dereg_ioat(pbdev);
 695    }
 696
 697    pbdev->state = ZPCI_FS_STANDBY;
 698    s390_pci_generate_plug_event(HP_EVENT_CONFIGURED_TO_STBRES,
 699                                 pbdev->fh, pbdev->fid);
 700    qdev_unplug(DEVICE(pbdev), NULL);
 701}
 702
 703static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
 704                                    DeviceState *dev, Error **errp)
 705{
 706    int i;
 707    PCIDevice *pci_dev = NULL;
 708    S390PCIBusDevice *pbdev = NULL;
 709    S390pciState *s = s390_get_phb();
 710
 711    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
 712        pci_dev = PCI_DEVICE(dev);
 713
 714        for (i = 0 ; i < PCI_SLOT_MAX; i++) {
 715            if (s->pbdev[i] && s->pbdev[i]->pdev == pci_dev) {
 716                pbdev = s->pbdev[i];
 717                break;
 718            }
 719        }
 720
 721        if (!pbdev) {
 722            object_unparent(OBJECT(pci_dev));
 723            return;
 724        }
 725    } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
 726        pbdev = S390_PCI_DEVICE(dev);
 727        pci_dev = pbdev->pdev;
 728    }
 729
 730    switch (pbdev->state) {
 731    case ZPCI_FS_RESERVED:
 732        goto out;
 733    case ZPCI_FS_STANDBY:
 734        break;
 735    default:
 736        s390_pci_generate_plug_event(HP_EVENT_DECONFIGURE_REQUEST,
 737                                     pbdev->fh, pbdev->fid);
 738        pbdev->release_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
 739                                            s390_pcihost_timer_cb,
 740                                            pbdev);
 741        timer_mod(pbdev->release_timer,
 742                  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + HOT_UNPLUG_TIMEOUT);
 743        return;
 744    }
 745
 746    if (pbdev->release_timer && timer_pending(pbdev->release_timer)) {
 747        timer_del(pbdev->release_timer);
 748        timer_free(pbdev->release_timer);
 749        pbdev->release_timer = NULL;
 750    }
 751
 752    s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,
 753                                 pbdev->fh, pbdev->fid);
 754    object_unparent(OBJECT(pci_dev));
 755    pbdev->pdev = NULL;
 756    pbdev->state = ZPCI_FS_RESERVED;
 757out:
 758    pbdev->fid = 0;
 759    s->pbdev[pbdev->fh & FH_MASK_INDEX] = NULL;
 760    object_unparent(OBJECT(pbdev));
 761}
 762
 763static void s390_pcihost_class_init(ObjectClass *klass, void *data)
 764{
 765    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 766    DeviceClass *dc = DEVICE_CLASS(klass);
 767    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
 768
 769    dc->cannot_instantiate_with_device_add_yet = true;
 770    k->init = s390_pcihost_init;
 771    hc->plug = s390_pcihost_hot_plug;
 772    hc->unplug = s390_pcihost_hot_unplug;
 773    msi_nonbroken = true;
 774}
 775
 776static const TypeInfo s390_pcihost_info = {
 777    .name          = TYPE_S390_PCI_HOST_BRIDGE,
 778    .parent        = TYPE_PCI_HOST_BRIDGE,
 779    .instance_size = sizeof(S390pciState),
 780    .class_init    = s390_pcihost_class_init,
 781    .interfaces = (InterfaceInfo[]) {
 782        { TYPE_HOTPLUG_HANDLER },
 783        { }
 784    }
 785};
 786
 787static const TypeInfo s390_pcibus_info = {
 788    .name = TYPE_S390_PCI_BUS,
 789    .parent = TYPE_BUS,
 790    .instance_size = sizeof(S390PCIBus),
 791};
 792
 793static uint16_t s390_pci_generate_uid(void)
 794{
 795    uint16_t uid = 0;
 796
 797    do {
 798        uid++;
 799        if (!s390_pci_find_dev_by_uid(uid)) {
 800            return uid;
 801        }
 802    } while (uid < ZPCI_MAX_UID);
 803
 804    return UID_UNDEFINED;
 805}
 806
 807static uint32_t s390_pci_generate_fid(Error **errp)
 808{
 809    uint32_t fid = 0;
 810
 811    while (fid <= ZPCI_MAX_FID) {
 812        if (!s390_pci_find_dev_by_fid(fid)) {
 813            return fid;
 814        }
 815
 816        if (fid == ZPCI_MAX_FID) {
 817            break;
 818        }
 819
 820        fid++;
 821    }
 822
 823    error_setg(errp, "no free fid could be found");
 824    return 0;
 825}
 826
 827static void s390_pci_device_realize(DeviceState *dev, Error **errp)
 828{
 829    S390PCIBusDevice *zpci = S390_PCI_DEVICE(dev);
 830
 831    if (!zpci->target) {
 832        error_setg(errp, "target must be defined");
 833        return;
 834    }
 835
 836    if (s390_pci_find_dev_by_target(zpci->target)) {
 837        error_setg(errp, "target %s already has an associated zpci device",
 838                   zpci->target);
 839        return;
 840    }
 841
 842    if (zpci->uid == UID_UNDEFINED) {
 843        zpci->uid = s390_pci_generate_uid();
 844        if (!zpci->uid) {
 845            error_setg(errp, "no free uid could be found");
 846            return;
 847        }
 848    } else if (s390_pci_find_dev_by_uid(zpci->uid)) {
 849        error_setg(errp, "uid %u already in use", zpci->uid);
 850        return;
 851    }
 852
 853    if (!zpci->fid_defined) {
 854        Error *local_error = NULL;
 855
 856        zpci->fid = s390_pci_generate_fid(&local_error);
 857        if (local_error) {
 858            error_propagate(errp, local_error);
 859            return;
 860        }
 861    } else if (s390_pci_find_dev_by_fid(zpci->fid)) {
 862        error_setg(errp, "fid %u already in use", zpci->fid);
 863        return;
 864    }
 865
 866    zpci->state = ZPCI_FS_RESERVED;
 867}
 868
 869static void s390_pci_device_reset(DeviceState *dev)
 870{
 871    S390PCIBusDevice *pbdev = S390_PCI_DEVICE(dev);
 872
 873    switch (pbdev->state) {
 874    case ZPCI_FS_RESERVED:
 875        return;
 876    case ZPCI_FS_STANDBY:
 877        break;
 878    default:
 879        pbdev->fh &= ~FH_MASK_ENABLE;
 880        pbdev->state = ZPCI_FS_DISABLED;
 881        break;
 882    }
 883
 884    if (pbdev->summary_ind) {
 885        pci_dereg_irqs(pbdev);
 886    }
 887    if (pbdev->iommu_enabled) {
 888        pci_dereg_ioat(pbdev);
 889    }
 890
 891    pbdev->fmb_addr = 0;
 892}
 893
 894static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
 895                         void *opaque, Error **errp)
 896{
 897    Property *prop = opaque;
 898    uint32_t *ptr = qdev_get_prop_ptr(DEVICE(obj), prop);
 899
 900    visit_type_uint32(v, name, ptr, errp);
 901}
 902
 903static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
 904                         void *opaque, Error **errp)
 905{
 906    DeviceState *dev = DEVICE(obj);
 907    S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
 908    Property *prop = opaque;
 909    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
 910
 911    if (dev->realized) {
 912        qdev_prop_set_after_realize(dev, name, errp);
 913        return;
 914    }
 915
 916    visit_type_uint32(v, name, ptr, errp);
 917    zpci->fid_defined = true;
 918}
 919
 920static PropertyInfo s390_pci_fid_propinfo = {
 921    .name = "zpci_fid",
 922    .get = s390_pci_get_fid,
 923    .set = s390_pci_set_fid,
 924};
 925
 926#define DEFINE_PROP_S390_PCI_FID(_n, _s, _f) \
 927    DEFINE_PROP(_n, _s, _f, s390_pci_fid_propinfo, uint32_t)
 928
 929static Property s390_pci_device_properties[] = {
 930    DEFINE_PROP_UINT16("uid", S390PCIBusDevice, uid, UID_UNDEFINED),
 931    DEFINE_PROP_S390_PCI_FID("fid", S390PCIBusDevice, fid),
 932    DEFINE_PROP_STRING("target", S390PCIBusDevice, target),
 933    DEFINE_PROP_END_OF_LIST(),
 934};
 935
 936static void s390_pci_device_class_init(ObjectClass *klass, void *data)
 937{
 938    DeviceClass *dc = DEVICE_CLASS(klass);
 939
 940    dc->desc = "zpci device";
 941    dc->reset = s390_pci_device_reset;
 942    dc->bus_type = TYPE_S390_PCI_BUS;
 943    dc->realize = s390_pci_device_realize;
 944    dc->props = s390_pci_device_properties;
 945}
 946
 947static const TypeInfo s390_pci_device_info = {
 948    .name = TYPE_S390_PCI_DEVICE,
 949    .parent = TYPE_DEVICE,
 950    .instance_size = sizeof(S390PCIBusDevice),
 951    .class_init = s390_pci_device_class_init,
 952};
 953
 954static void s390_pci_register_types(void)
 955{
 956    type_register_static(&s390_pcihost_info);
 957    type_register_static(&s390_pcibus_info);
 958    type_register_static(&s390_pci_device_info);
 959}
 960
 961type_init(s390_pci_register_types)
 962