qemu/hw/s390x/sclp.c
<<
>>
Prefs
   1/*
   2 * SCLP Support
   3 *
   4 * Copyright IBM, Corp. 2012
   5 *
   6 * Authors:
   7 *  Christian Borntraeger <borntraeger@de.ibm.com>
   8 *  Heinz Graalfs <graalfs@linux.vnet.ibm.com>
   9 *
  10 * This work is licensed under the terms of the GNU GPL, version 2 or (at your
  11 * option) any later version.  See the COPYING file in the top-level directory.
  12 *
  13 */
  14
  15#include "qemu/osdep.h"
  16#include "qapi/error.h"
  17#include "cpu.h"
  18#include "sysemu/kvm.h"
  19#include "exec/memory.h"
  20#include "sysemu/sysemu.h"
  21#include "exec/address-spaces.h"
  22#include "hw/boards.h"
  23#include "hw/s390x/sclp.h"
  24#include "hw/s390x/event-facility.h"
  25#include "hw/s390x/s390-pci-bus.h"
  26#include "hw/s390x/ipl.h"
  27
  28static inline SCLPDevice *get_sclp_device(void)
  29{
  30    static SCLPDevice *sclp;
  31
  32    if (!sclp) {
  33        sclp = SCLP(object_resolve_path_type("", TYPE_SCLP, NULL));
  34    }
  35    return sclp;
  36}
  37
  38static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int count)
  39{
  40    uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
  41    int i;
  42
  43    s390_get_feat_block(S390_FEAT_TYPE_SCLP_CPU, features);
  44    for (i = 0; i < count; i++) {
  45        entry[i].address = i;
  46        entry[i].type = 0;
  47        memcpy(entry[i].features, features, sizeof(entry[i].features));
  48    }
  49}
  50
  51/* Provide information about the configuration, CPUs and storage */
  52static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
  53{
  54    ReadInfo *read_info = (ReadInfo *) sccb;
  55    MachineState *machine = MACHINE(qdev_get_machine());
  56    sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
  57    CPUState *cpu;
  58    int cpu_count = 0;
  59    int rnsize, rnmax;
  60    int slots = MIN(machine->ram_slots, s390_get_memslot_count(kvm_state));
  61    IplParameterBlock *ipib = s390_ipl_get_iplb();
  62
  63    CPU_FOREACH(cpu) {
  64        cpu_count++;
  65    }
  66
  67    /* CPU information */
  68    read_info->entries_cpu = cpu_to_be16(cpu_count);
  69    read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
  70    read_info->highest_cpu = cpu_to_be16(max_cpus);
  71
  72    read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
  73
  74    /* Configuration Characteristic (Extension) */
  75    s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR,
  76                         read_info->conf_char);
  77    s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
  78                         read_info->conf_char_ext);
  79
  80    prepare_cpu_entries(sclp, read_info->entries, cpu_count);
  81
  82    read_info->facilities = cpu_to_be64(SCLP_HAS_CPU_INFO |
  83                                        SCLP_HAS_PCI_RECONFIG);
  84
  85    /* Memory Hotplug is only supported for the ccw machine type */
  86    if (mhd) {
  87        mhd->standby_subregion_size = MEM_SECTION_SIZE;
  88        /* Deduct the memory slot already used for core */
  89        if (slots > 0) {
  90            while ((mhd->standby_subregion_size * (slots - 1)
  91                    < mhd->standby_mem_size)) {
  92                mhd->standby_subregion_size = mhd->standby_subregion_size << 1;
  93            }
  94        }
  95        /*
  96         * Initialize mapping of guest standby memory sections indicating which
  97         * are and are not online. Assume all standby memory begins offline.
  98         */
  99        if (mhd->standby_state_map == 0) {
 100            if (mhd->standby_mem_size % mhd->standby_subregion_size) {
 101                mhd->standby_state_map = g_malloc0((mhd->standby_mem_size /
 102                                             mhd->standby_subregion_size + 1) *
 103                                             (mhd->standby_subregion_size /
 104                                             MEM_SECTION_SIZE));
 105            } else {
 106                mhd->standby_state_map = g_malloc0(mhd->standby_mem_size /
 107                                                   MEM_SECTION_SIZE);
 108            }
 109        }
 110        mhd->padded_ram_size = ram_size + mhd->pad_size;
 111        mhd->rzm = 1 << mhd->increment_size;
 112
 113        read_info->facilities |= cpu_to_be64(SCLP_FC_ASSIGN_ATTACH_READ_STOR);
 114    }
 115    read_info->mha_pow = s390_get_mha_pow();
 116    read_info->hmfai = cpu_to_be32(s390_get_hmfai());
 117
 118    rnsize = 1 << (sclp->increment_size - 20);
 119    if (rnsize <= 128) {
 120        read_info->rnsize = rnsize;
 121    } else {
 122        read_info->rnsize = 0;
 123        read_info->rnsize2 = cpu_to_be32(rnsize);
 124    }
 125
 126    rnmax = machine->maxram_size >> sclp->increment_size;
 127    if (rnmax < 0x10000) {
 128        read_info->rnmax = cpu_to_be16(rnmax);
 129    } else {
 130        read_info->rnmax = cpu_to_be16(0);
 131        read_info->rnmax2 = cpu_to_be64(rnmax);
 132    }
 133
 134    if (ipib && ipib->flags & DIAG308_FLAGS_LP_VALID) {
 135        memcpy(&read_info->loadparm, &ipib->loadparm,
 136               sizeof(read_info->loadparm));
 137    } else {
 138        s390_ipl_set_loadparm(read_info->loadparm);
 139    }
 140
 141    sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
 142}
 143
 144static void read_storage_element0_info(SCLPDevice *sclp, SCCB *sccb)
 145{
 146    int i, assigned;
 147    int subincrement_id = SCLP_STARTING_SUBINCREMENT_ID;
 148    ReadStorageElementInfo *storage_info = (ReadStorageElementInfo *) sccb;
 149    sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
 150
 151    if (!mhd) {
 152        sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
 153        return;
 154    }
 155
 156    if ((ram_size >> mhd->increment_size) >= 0x10000) {
 157        sccb->h.response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
 158        return;
 159    }
 160
 161    /* Return information regarding core memory */
 162    storage_info->max_id = cpu_to_be16(mhd->standby_mem_size ? 1 : 0);
 163    assigned = ram_size >> mhd->increment_size;
 164    storage_info->assigned = cpu_to_be16(assigned);
 165
 166    for (i = 0; i < assigned; i++) {
 167        storage_info->entries[i] = cpu_to_be32(subincrement_id);
 168        subincrement_id += SCLP_INCREMENT_UNIT;
 169    }
 170    sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
 171}
 172
 173static void read_storage_element1_info(SCLPDevice *sclp, SCCB *sccb)
 174{
 175    ReadStorageElementInfo *storage_info = (ReadStorageElementInfo *) sccb;
 176    sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
 177
 178    if (!mhd) {
 179        sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
 180        return;
 181    }
 182
 183    if ((mhd->standby_mem_size >> mhd->increment_size) >= 0x10000) {
 184        sccb->h.response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
 185        return;
 186    }
 187
 188    /* Return information regarding standby memory */
 189    storage_info->max_id = cpu_to_be16(mhd->standby_mem_size ? 1 : 0);
 190    storage_info->assigned = cpu_to_be16(mhd->standby_mem_size >>
 191                                         mhd->increment_size);
 192    storage_info->standby = cpu_to_be16(mhd->standby_mem_size >>
 193                                        mhd->increment_size);
 194    sccb->h.response_code = cpu_to_be16(SCLP_RC_STANDBY_READ_COMPLETION);
 195}
 196
 197static void attach_storage_element(SCLPDevice *sclp, SCCB *sccb,
 198                                   uint16_t element)
 199{
 200    int i, assigned, subincrement_id;
 201    AttachStorageElement *attach_info = (AttachStorageElement *) sccb;
 202    sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
 203
 204    if (!mhd) {
 205        sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
 206        return;
 207    }
 208
 209    if (element != 1) {
 210        sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
 211        return;
 212    }
 213
 214    assigned = mhd->standby_mem_size >> mhd->increment_size;
 215    attach_info->assigned = cpu_to_be16(assigned);
 216    subincrement_id = ((ram_size >> mhd->increment_size) << 16)
 217                      + SCLP_STARTING_SUBINCREMENT_ID;
 218    for (i = 0; i < assigned; i++) {
 219        attach_info->entries[i] = cpu_to_be32(subincrement_id);
 220        subincrement_id += SCLP_INCREMENT_UNIT;
 221    }
 222    sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);
 223}
 224
 225static void assign_storage(SCLPDevice *sclp, SCCB *sccb)
 226{
 227    MemoryRegion *mr = NULL;
 228    uint64_t this_subregion_size;
 229    AssignStorage *assign_info = (AssignStorage *) sccb;
 230    sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
 231    ram_addr_t assign_addr;
 232    MemoryRegion *sysmem = get_system_memory();
 233
 234    if (!mhd) {
 235        sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
 236        return;
 237    }
 238    assign_addr = (assign_info->rn - 1) * mhd->rzm;
 239
 240    if ((assign_addr % MEM_SECTION_SIZE == 0) &&
 241        (assign_addr >= mhd->padded_ram_size)) {
 242        /* Re-use existing memory region if found */
 243        mr = memory_region_find(sysmem, assign_addr, 1).mr;
 244        memory_region_unref(mr);
 245        if (!mr) {
 246
 247            MemoryRegion *standby_ram = g_new(MemoryRegion, 1);
 248
 249            /* offset to align to standby_subregion_size for allocation */
 250            ram_addr_t offset = assign_addr -
 251                                (assign_addr - mhd->padded_ram_size)
 252                                % mhd->standby_subregion_size;
 253
 254            /* strlen("standby.ram") + 4 (Max of KVM_MEMORY_SLOTS) +  NULL */
 255            char id[16];
 256            snprintf(id, 16, "standby.ram%d",
 257                     (int)((offset - mhd->padded_ram_size) /
 258                     mhd->standby_subregion_size) + 1);
 259
 260            /* Allocate a subregion of the calculated standby_subregion_size */
 261            if (offset + mhd->standby_subregion_size >
 262                mhd->padded_ram_size + mhd->standby_mem_size) {
 263                this_subregion_size = mhd->padded_ram_size +
 264                  mhd->standby_mem_size - offset;
 265            } else {
 266                this_subregion_size = mhd->standby_subregion_size;
 267            }
 268
 269            memory_region_init_ram(standby_ram, NULL, id, this_subregion_size,
 270                                   &error_fatal);
 271            /* This is a hack to make memory hotunplug work again. Once we have
 272             * subdevices, we have to unparent them when unassigning memory,
 273             * instead of doing it via the ref count of the MemoryRegion. */
 274            object_ref(OBJECT(standby_ram));
 275            object_unparent(OBJECT(standby_ram));
 276            memory_region_add_subregion(sysmem, offset, standby_ram);
 277        }
 278        /* The specified subregion is no longer in standby */
 279        mhd->standby_state_map[(assign_addr - mhd->padded_ram_size)
 280                               / MEM_SECTION_SIZE] = 1;
 281    }
 282    sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);
 283}
 284
 285static void unassign_storage(SCLPDevice *sclp, SCCB *sccb)
 286{
 287    MemoryRegion *mr = NULL;
 288    AssignStorage *assign_info = (AssignStorage *) sccb;
 289    sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
 290    ram_addr_t unassign_addr;
 291    MemoryRegion *sysmem = get_system_memory();
 292
 293    if (!mhd) {
 294        sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
 295        return;
 296    }
 297    unassign_addr = (assign_info->rn - 1) * mhd->rzm;
 298
 299    /* if the addr is a multiple of 256 MB */
 300    if ((unassign_addr % MEM_SECTION_SIZE == 0) &&
 301        (unassign_addr >= mhd->padded_ram_size)) {
 302        mhd->standby_state_map[(unassign_addr -
 303                           mhd->padded_ram_size) / MEM_SECTION_SIZE] = 0;
 304
 305        /* find the specified memory region and destroy it */
 306        mr = memory_region_find(sysmem, unassign_addr, 1).mr;
 307        memory_region_unref(mr);
 308        if (mr) {
 309            int i;
 310            int is_removable = 1;
 311            ram_addr_t map_offset = (unassign_addr - mhd->padded_ram_size -
 312                                     (unassign_addr - mhd->padded_ram_size)
 313                                     % mhd->standby_subregion_size);
 314            /* Mark all affected subregions as 'standby' once again */
 315            for (i = 0;
 316                 i < (mhd->standby_subregion_size / MEM_SECTION_SIZE);
 317                 i++) {
 318
 319                if (mhd->standby_state_map[i + map_offset / MEM_SECTION_SIZE]) {
 320                    is_removable = 0;
 321                    break;
 322                }
 323            }
 324            if (is_removable) {
 325                memory_region_del_subregion(sysmem, mr);
 326                object_unref(OBJECT(mr));
 327            }
 328        }
 329    }
 330    sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);
 331}
 332
 333/* Provide information about the CPU */
 334static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
 335{
 336    ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
 337    CPUState *cpu;
 338    int cpu_count = 0;
 339
 340    CPU_FOREACH(cpu) {
 341        cpu_count++;
 342    }
 343
 344    cpu_info->nr_configured = cpu_to_be16(cpu_count);
 345    cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
 346    cpu_info->nr_standby = cpu_to_be16(0);
 347
 348    /* The standby offset is 16-byte for each CPU */
 349    cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured
 350        + cpu_info->nr_configured*sizeof(CPUEntry));
 351
 352    prepare_cpu_entries(sclp, cpu_info->entries, cpu_count);
 353
 354    sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
 355}
 356
 357static void sclp_execute(SCLPDevice *sclp, SCCB *sccb, uint32_t code)
 358{
 359    SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
 360    SCLPEventFacility *ef = sclp->event_facility;
 361    SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef);
 362
 363    switch (code & SCLP_CMD_CODE_MASK) {
 364    case SCLP_CMDW_READ_SCP_INFO:
 365    case SCLP_CMDW_READ_SCP_INFO_FORCED:
 366        sclp_c->read_SCP_info(sclp, sccb);
 367        break;
 368    case SCLP_CMDW_READ_CPU_INFO:
 369        sclp_c->read_cpu_info(sclp, sccb);
 370        break;
 371    case SCLP_READ_STORAGE_ELEMENT_INFO:
 372        if (code & 0xff00) {
 373            sclp_c->read_storage_element1_info(sclp, sccb);
 374        } else {
 375            sclp_c->read_storage_element0_info(sclp, sccb);
 376        }
 377        break;
 378    case SCLP_ATTACH_STORAGE_ELEMENT:
 379        sclp_c->attach_storage_element(sclp, sccb, (code & 0xff00) >> 8);
 380        break;
 381    case SCLP_ASSIGN_STORAGE:
 382        sclp_c->assign_storage(sclp, sccb);
 383        break;
 384    case SCLP_UNASSIGN_STORAGE:
 385        sclp_c->unassign_storage(sclp, sccb);
 386        break;
 387    case SCLP_CMDW_CONFIGURE_PCI:
 388        s390_pci_sclp_configure(sccb);
 389        break;
 390    case SCLP_CMDW_DECONFIGURE_PCI:
 391        s390_pci_sclp_deconfigure(sccb);
 392        break;
 393    default:
 394        efc->command_handler(ef, sccb, code);
 395        break;
 396    }
 397}
 398
 399int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
 400{
 401    SCLPDevice *sclp = get_sclp_device();
 402    SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
 403    int r = 0;
 404    SCCB work_sccb;
 405
 406    hwaddr sccb_len = sizeof(SCCB);
 407
 408    /* first some basic checks on program checks */
 409    if (env->psw.mask & PSW_MASK_PSTATE) {
 410        r = -PGM_PRIVILEGED;
 411        goto out;
 412    }
 413    if (cpu_physical_memory_is_io(sccb)) {
 414        r = -PGM_ADDRESSING;
 415        goto out;
 416    }
 417    if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa
 418        || (sccb & ~0x7ffffff8UL) != 0) {
 419        r = -PGM_SPECIFICATION;
 420        goto out;
 421    }
 422
 423    /*
 424     * we want to work on a private copy of the sccb, to prevent guests
 425     * from playing dirty tricks by modifying the memory content after
 426     * the host has checked the values
 427     */
 428    cpu_physical_memory_read(sccb, &work_sccb, sccb_len);
 429
 430    /* Valid sccb sizes */
 431    if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader) ||
 432        be16_to_cpu(work_sccb.h.length) > SCCB_SIZE) {
 433        r = -PGM_SPECIFICATION;
 434        goto out;
 435    }
 436
 437    sclp_c->execute(sclp, &work_sccb, code);
 438
 439    cpu_physical_memory_write(sccb, &work_sccb,
 440                              be16_to_cpu(work_sccb.h.length));
 441
 442    sclp_c->service_interrupt(sclp, sccb);
 443
 444out:
 445    return r;
 446}
 447
 448static void service_interrupt(SCLPDevice *sclp, uint32_t sccb)
 449{
 450    SCLPEventFacility *ef = sclp->event_facility;
 451    SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef);
 452
 453    uint32_t param = sccb & ~3;
 454
 455    /* Indicate whether an event is still pending */
 456    param |= efc->event_pending(ef) ? 1 : 0;
 457
 458    if (!param) {
 459        /* No need to send an interrupt, there's nothing to be notified about */
 460        return;
 461    }
 462    s390_sclp_extint(param);
 463}
 464
 465void sclp_service_interrupt(uint32_t sccb)
 466{
 467    SCLPDevice *sclp = get_sclp_device();
 468    SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
 469
 470    sclp_c->service_interrupt(sclp, sccb);
 471}
 472
 473/* qemu object creation and initialization functions */
 474
 475void s390_sclp_init(void)
 476{
 477    Object *new = object_new(TYPE_SCLP);
 478
 479    object_property_add_child(qdev_get_machine(), TYPE_SCLP, new,
 480                              NULL);
 481    object_unref(OBJECT(new));
 482    qdev_init_nofail(DEVICE(new));
 483}
 484
 485static void sclp_realize(DeviceState *dev, Error **errp)
 486{
 487    MachineState *machine = MACHINE(qdev_get_machine());
 488    SCLPDevice *sclp = SCLP(dev);
 489    Error *err = NULL;
 490    uint64_t hw_limit;
 491    int ret;
 492
 493    object_property_set_bool(OBJECT(sclp->event_facility), true, "realized",
 494                             &err);
 495    if (err) {
 496        goto out;
 497    }
 498    /*
 499     * qdev_device_add searches the sysbus for TYPE_SCLP_EVENTS_BUS. As long
 500     * as we can't find a fitting bus via the qom tree, we have to add the
 501     * event facility to the sysbus, so e.g. a sclp console can be created.
 502     */
 503    qdev_set_parent_bus(DEVICE(sclp->event_facility), sysbus_get_default());
 504
 505    ret = s390_set_memory_limit(machine->maxram_size, &hw_limit);
 506    if (ret == -E2BIG) {
 507        error_setg(&err, "host supports a maximum of %" PRIu64 " GB",
 508                   hw_limit >> 30);
 509    } else if (ret) {
 510        error_setg(&err, "setting the guest size failed");
 511    }
 512
 513out:
 514    error_propagate(errp, err);
 515}
 516
 517static void sclp_memory_init(SCLPDevice *sclp)
 518{
 519    MachineState *machine = MACHINE(qdev_get_machine());
 520    ram_addr_t initial_mem = machine->ram_size;
 521    ram_addr_t max_mem = machine->maxram_size;
 522    ram_addr_t standby_mem = max_mem - initial_mem;
 523    ram_addr_t pad_mem = 0;
 524    int increment_size = 20;
 525
 526    /* The storage increment size is a multiple of 1M and is a power of 2.
 527     * The number of storage increments must be MAX_STORAGE_INCREMENTS or fewer.
 528     * The variable 'increment_size' is an exponent of 2 that can be
 529     * used to calculate the size (in bytes) of an increment. */
 530    while ((initial_mem >> increment_size) > MAX_STORAGE_INCREMENTS) {
 531        increment_size++;
 532    }
 533    if (machine->ram_slots) {
 534        while ((standby_mem >> increment_size) > MAX_STORAGE_INCREMENTS) {
 535            increment_size++;
 536        }
 537    }
 538    sclp->increment_size = increment_size;
 539
 540    /* The core and standby memory areas need to be aligned with
 541     * the increment size.  In effect, this can cause the
 542     * user-specified memory size to be rounded down to align
 543     * with the nearest increment boundary. */
 544    initial_mem = initial_mem >> increment_size << increment_size;
 545    standby_mem = standby_mem >> increment_size << increment_size;
 546
 547    /* If the size of ram is not on a MEM_SECTION_SIZE boundary,
 548       calculate the pad size necessary to force this boundary. */
 549    if (machine->ram_slots && standby_mem) {
 550        sclpMemoryHotplugDev *mhd = init_sclp_memory_hotplug_dev();
 551
 552        if (initial_mem % MEM_SECTION_SIZE) {
 553            pad_mem = MEM_SECTION_SIZE - initial_mem % MEM_SECTION_SIZE;
 554        }
 555        mhd->increment_size = increment_size;
 556        mhd->pad_size = pad_mem;
 557        mhd->standby_mem_size = standby_mem;
 558    }
 559    machine->ram_size = initial_mem;
 560    machine->maxram_size = initial_mem + pad_mem + standby_mem;
 561    /* let's propagate the changed ram size into the global variable. */
 562    ram_size = initial_mem;
 563}
 564
 565static void sclp_init(Object *obj)
 566{
 567    SCLPDevice *sclp = SCLP(obj);
 568    Object *new;
 569
 570    new = object_new(TYPE_SCLP_EVENT_FACILITY);
 571    object_property_add_child(obj, TYPE_SCLP_EVENT_FACILITY, new, NULL);
 572    object_unref(new);
 573    sclp->event_facility = EVENT_FACILITY(new);
 574
 575    sclp_memory_init(sclp);
 576}
 577
 578static void sclp_class_init(ObjectClass *oc, void *data)
 579{
 580    SCLPDeviceClass *sc = SCLP_CLASS(oc);
 581    DeviceClass *dc = DEVICE_CLASS(oc);
 582
 583    dc->desc = "SCLP (Service-Call Logical Processor)";
 584    dc->realize = sclp_realize;
 585    dc->hotpluggable = false;
 586    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 587
 588    sc->read_SCP_info = read_SCP_info;
 589    sc->read_storage_element0_info = read_storage_element0_info;
 590    sc->read_storage_element1_info = read_storage_element1_info;
 591    sc->attach_storage_element = attach_storage_element;
 592    sc->assign_storage = assign_storage;
 593    sc->unassign_storage = unassign_storage;
 594    sc->read_cpu_info = sclp_read_cpu_info;
 595    sc->execute = sclp_execute;
 596    sc->service_interrupt = service_interrupt;
 597}
 598
 599static TypeInfo sclp_info = {
 600    .name = TYPE_SCLP,
 601    .parent = TYPE_DEVICE,
 602    .instance_init = sclp_init,
 603    .instance_size = sizeof(SCLPDevice),
 604    .class_init = sclp_class_init,
 605    .class_size = sizeof(SCLPDeviceClass),
 606};
 607
 608sclpMemoryHotplugDev *init_sclp_memory_hotplug_dev(void)
 609{
 610    DeviceState *dev;
 611    dev = qdev_create(NULL, TYPE_SCLP_MEMORY_HOTPLUG_DEV);
 612    object_property_add_child(qdev_get_machine(),
 613                              TYPE_SCLP_MEMORY_HOTPLUG_DEV,
 614                              OBJECT(dev), NULL);
 615    qdev_init_nofail(dev);
 616    return SCLP_MEMORY_HOTPLUG_DEV(object_resolve_path(
 617                                   TYPE_SCLP_MEMORY_HOTPLUG_DEV, NULL));
 618}
 619
 620sclpMemoryHotplugDev *get_sclp_memory_hotplug_dev(void)
 621{
 622    return SCLP_MEMORY_HOTPLUG_DEV(object_resolve_path(
 623                                   TYPE_SCLP_MEMORY_HOTPLUG_DEV, NULL));
 624}
 625
 626static void sclp_memory_hotplug_dev_class_init(ObjectClass *klass,
 627                                               void *data)
 628{
 629    DeviceClass *dc = DEVICE_CLASS(klass);
 630
 631    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 632}
 633
 634static TypeInfo sclp_memory_hotplug_dev_info = {
 635    .name = TYPE_SCLP_MEMORY_HOTPLUG_DEV,
 636    .parent = TYPE_SYS_BUS_DEVICE,
 637    .instance_size = sizeof(sclpMemoryHotplugDev),
 638    .class_init = sclp_memory_hotplug_dev_class_init,
 639};
 640
 641static void register_types(void)
 642{
 643    type_register_static(&sclp_memory_hotplug_dev_info);
 644    type_register_static(&sclp_info);
 645}
 646type_init(register_types);
 647