qemu/hw/ppc/spapr_drc.c
<<
>>
Prefs
   1/*
   2 * QEMU SPAPR Dynamic Reconfiguration Connector Implementation
   3 *
   4 * Copyright IBM Corp. 2014
   5 *
   6 * Authors:
   7 *  Michael Roth      <mdroth@linux.vnet.ibm.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  10 * See the COPYING file in the top-level directory.
  11 */
  12
  13#include "qemu/osdep.h"
  14#include "qapi/error.h"
  15#include "cpu.h"
  16#include "qemu/cutils.h"
  17#include "hw/ppc/spapr_drc.h"
  18#include "qom/object.h"
  19#include "hw/qdev.h"
  20#include "qapi/visitor.h"
  21#include "qemu/error-report.h"
  22#include "hw/ppc/spapr.h" /* for RTAS return codes */
  23
  24/* #define DEBUG_SPAPR_DRC */
  25
  26#ifdef DEBUG_SPAPR_DRC
  27#define DPRINTF(fmt, ...) \
  28    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
  29#define DPRINTFN(fmt, ...) \
  30    do { DPRINTF(fmt, ## __VA_ARGS__); fprintf(stderr, "\n"); } while (0)
  31#else
  32#define DPRINTF(fmt, ...) \
  33    do { } while (0)
  34#define DPRINTFN(fmt, ...) \
  35    do { } while (0)
  36#endif
  37
  38#define DRC_CONTAINER_PATH "/dr-connector"
  39#define DRC_INDEX_TYPE_SHIFT 28
  40#define DRC_INDEX_ID_MASK ((1ULL << DRC_INDEX_TYPE_SHIFT) - 1)
  41
  42static sPAPRDRConnectorTypeShift get_type_shift(sPAPRDRConnectorType type)
  43{
  44    uint32_t shift = 0;
  45
  46    /* make sure this isn't SPAPR_DR_CONNECTOR_TYPE_ANY, or some
  47     * other wonky value.
  48     */
  49    g_assert(is_power_of_2(type));
  50
  51    while (type != (1 << shift)) {
  52        shift++;
  53    }
  54    return shift;
  55}
  56
  57static uint32_t get_index(sPAPRDRConnector *drc)
  58{
  59    /* no set format for a drc index: it only needs to be globally
  60     * unique. this is how we encode the DRC type on bare-metal
  61     * however, so might as well do that here
  62     */
  63    return (get_type_shift(drc->type) << DRC_INDEX_TYPE_SHIFT) |
  64            (drc->id & DRC_INDEX_ID_MASK);
  65}
  66
  67static uint32_t set_isolation_state(sPAPRDRConnector *drc,
  68                                    sPAPRDRIsolationState state)
  69{
  70    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
  71
  72    DPRINTFN("drc: %x, set_isolation_state: %x", get_index(drc), state);
  73
  74    if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
  75        /* cannot unisolate a non-existant resource, and, or resources
  76         * which are in an 'UNUSABLE' allocation state. (PAPR 2.7, 13.5.3.5)
  77         */
  78        if (!drc->dev ||
  79            drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
  80            return RTAS_OUT_NO_SUCH_INDICATOR;
  81        }
  82    }
  83
  84    drc->isolation_state = state;
  85
  86    if (drc->isolation_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {
  87        /* if we're awaiting release, but still in an unconfigured state,
  88         * it's likely the guest is still in the process of configuring
  89         * the device and is transitioning the devices to an ISOLATED
  90         * state as a part of that process. so we only complete the
  91         * removal when this transition happens for a device in a
  92         * configured state, as suggested by the state diagram from
  93         * PAPR+ 2.7, 13.4
  94         */
  95        if (drc->awaiting_release) {
  96            if (drc->configured) {
  97                DPRINTFN("finalizing device removal");
  98                drck->detach(drc, DEVICE(drc->dev), drc->detach_cb,
  99                             drc->detach_cb_opaque, NULL);
 100            } else {
 101                DPRINTFN("deferring device removal on unconfigured device\n");
 102            }
 103        }
 104        drc->configured = false;
 105    }
 106
 107    return RTAS_OUT_SUCCESS;
 108}
 109
 110static uint32_t set_indicator_state(sPAPRDRConnector *drc,
 111                                    sPAPRDRIndicatorState state)
 112{
 113    DPRINTFN("drc: %x, set_indicator_state: %x", get_index(drc), state);
 114    drc->indicator_state = state;
 115    return RTAS_OUT_SUCCESS;
 116}
 117
 118static uint32_t set_allocation_state(sPAPRDRConnector *drc,
 119                                     sPAPRDRAllocationState state)
 120{
 121    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 122
 123    DPRINTFN("drc: %x, set_allocation_state: %x", get_index(drc), state);
 124
 125    if (state == SPAPR_DR_ALLOCATION_STATE_USABLE) {
 126        /* if there's no resource/device associated with the DRC, there's
 127         * no way for us to put it in an allocation state consistent with
 128         * being 'USABLE'. PAPR 2.7, 13.5.3.4 documents that this should
 129         * result in an RTAS return code of -3 / "no such indicator"
 130         */
 131        if (!drc->dev) {
 132            return RTAS_OUT_NO_SUCH_INDICATOR;
 133        }
 134    }
 135
 136    if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI) {
 137        drc->allocation_state = state;
 138        if (drc->awaiting_release &&
 139            drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
 140            DPRINTFN("finalizing device removal");
 141            drck->detach(drc, DEVICE(drc->dev), drc->detach_cb,
 142                         drc->detach_cb_opaque, NULL);
 143        } else if (drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE) {
 144            drc->awaiting_allocation = false;
 145        }
 146    }
 147    return RTAS_OUT_SUCCESS;
 148}
 149
 150static uint32_t get_type(sPAPRDRConnector *drc)
 151{
 152    return drc->type;
 153}
 154
 155static const char *get_name(sPAPRDRConnector *drc)
 156{
 157    return drc->name;
 158}
 159
 160static const void *get_fdt(sPAPRDRConnector *drc, int *fdt_start_offset)
 161{
 162    if (fdt_start_offset) {
 163        *fdt_start_offset = drc->fdt_start_offset;
 164    }
 165    return drc->fdt;
 166}
 167
 168static void set_configured(sPAPRDRConnector *drc)
 169{
 170    DPRINTFN("drc: %x, set_configured", get_index(drc));
 171
 172    if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
 173        /* guest should be not configuring an isolated device */
 174        DPRINTFN("drc: %x, set_configured: skipping isolated device",
 175                 get_index(drc));
 176        return;
 177    }
 178    drc->configured = true;
 179}
 180
 181/* has the guest been notified of device attachment? */
 182static void set_signalled(sPAPRDRConnector *drc)
 183{
 184    drc->signalled = true;
 185}
 186
 187/*
 188 * dr-entity-sense sensor value
 189 * returned via get-sensor-state RTAS calls
 190 * as expected by state diagram in PAPR+ 2.7, 13.4
 191 * based on the current allocation/indicator/power states
 192 * for the DR connector.
 193 */
 194static uint32_t entity_sense(sPAPRDRConnector *drc, sPAPRDREntitySense *state)
 195{
 196    if (drc->dev) {
 197        if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI &&
 198            drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
 199            /* for logical DR, we return a state of UNUSABLE
 200             * iff the allocation state UNUSABLE.
 201             * Otherwise, report the state as USABLE/PRESENT,
 202             * as we would for PCI.
 203             */
 204            *state = SPAPR_DR_ENTITY_SENSE_UNUSABLE;
 205        } else {
 206            /* this assumes all PCI devices are assigned to
 207             * a 'live insertion' power domain, where QEMU
 208             * manages power state automatically as opposed
 209             * to the guest. present, non-PCI resources are
 210             * unaffected by power state.
 211             */
 212            *state = SPAPR_DR_ENTITY_SENSE_PRESENT;
 213        }
 214    } else {
 215        if (drc->type == SPAPR_DR_CONNECTOR_TYPE_PCI) {
 216            /* PCI devices, and only PCI devices, use EMPTY
 217             * in cases where we'd otherwise use UNUSABLE
 218             */
 219            *state = SPAPR_DR_ENTITY_SENSE_EMPTY;
 220        } else {
 221            *state = SPAPR_DR_ENTITY_SENSE_UNUSABLE;
 222        }
 223    }
 224
 225    DPRINTFN("drc: %x, entity_sense: %x", get_index(drc), state);
 226    return RTAS_OUT_SUCCESS;
 227}
 228
 229static void prop_get_index(Object *obj, Visitor *v, const char *name,
 230                           void *opaque, Error **errp)
 231{
 232    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
 233    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 234    uint32_t value = (uint32_t)drck->get_index(drc);
 235    visit_type_uint32(v, name, &value, errp);
 236}
 237
 238static void prop_get_type(Object *obj, Visitor *v, const char *name,
 239                          void *opaque, Error **errp)
 240{
 241    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
 242    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 243    uint32_t value = (uint32_t)drck->get_type(drc);
 244    visit_type_uint32(v, name, &value, errp);
 245}
 246
 247static char *prop_get_name(Object *obj, Error **errp)
 248{
 249    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
 250    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 251    return g_strdup(drck->get_name(drc));
 252}
 253
 254static void prop_get_entity_sense(Object *obj, Visitor *v, const char *name,
 255                                  void *opaque, Error **errp)
 256{
 257    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
 258    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 259    uint32_t value;
 260
 261    drck->entity_sense(drc, &value);
 262    visit_type_uint32(v, name, &value, errp);
 263}
 264
 265static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
 266                         void *opaque, Error **errp)
 267{
 268    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
 269    Error *err = NULL;
 270    int fdt_offset_next, fdt_offset, fdt_depth;
 271    void *fdt;
 272
 273    if (!drc->fdt) {
 274        visit_type_null(v, NULL, errp);
 275        return;
 276    }
 277
 278    fdt = drc->fdt;
 279    fdt_offset = drc->fdt_start_offset;
 280    fdt_depth = 0;
 281
 282    do {
 283        const char *name = NULL;
 284        const struct fdt_property *prop = NULL;
 285        int prop_len = 0, name_len = 0;
 286        uint32_t tag;
 287
 288        tag = fdt_next_tag(fdt, fdt_offset, &fdt_offset_next);
 289        switch (tag) {
 290        case FDT_BEGIN_NODE:
 291            fdt_depth++;
 292            name = fdt_get_name(fdt, fdt_offset, &name_len);
 293            visit_start_struct(v, name, NULL, 0, &err);
 294            if (err) {
 295                error_propagate(errp, err);
 296                return;
 297            }
 298            break;
 299        case FDT_END_NODE:
 300            /* shouldn't ever see an FDT_END_NODE before FDT_BEGIN_NODE */
 301            g_assert(fdt_depth > 0);
 302            visit_check_struct(v, &err);
 303            visit_end_struct(v, NULL);
 304            if (err) {
 305                error_propagate(errp, err);
 306                return;
 307            }
 308            fdt_depth--;
 309            break;
 310        case FDT_PROP: {
 311            int i;
 312            prop = fdt_get_property_by_offset(fdt, fdt_offset, &prop_len);
 313            name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
 314            visit_start_list(v, name, NULL, 0, &err);
 315            if (err) {
 316                error_propagate(errp, err);
 317                return;
 318            }
 319            for (i = 0; i < prop_len; i++) {
 320                visit_type_uint8(v, NULL, (uint8_t *)&prop->data[i], &err);
 321                if (err) {
 322                    error_propagate(errp, err);
 323                    return;
 324                }
 325            }
 326            visit_end_list(v, NULL);
 327            break;
 328        }
 329        default:
 330            error_setg(&error_abort, "device FDT in unexpected state: %d", tag);
 331        }
 332        fdt_offset = fdt_offset_next;
 333    } while (fdt_depth != 0);
 334}
 335
 336static void attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
 337                   int fdt_start_offset, bool coldplug, Error **errp)
 338{
 339    DPRINTFN("drc: %x, attach", get_index(drc));
 340
 341    if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {
 342        error_setg(errp, "an attached device is still awaiting release");
 343        return;
 344    }
 345    if (drc->type == SPAPR_DR_CONNECTOR_TYPE_PCI) {
 346        g_assert(drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE);
 347    }
 348    g_assert(fdt || coldplug);
 349
 350    /* NOTE: setting initial isolation state to UNISOLATED means we can't
 351     * detach unless guest has a userspace/kernel that moves this state
 352     * back to ISOLATED in response to an unplug event, or this is done
 353     * manually by the admin prior. if we force things while the guest
 354     * may be accessing the device, we can easily crash the guest, so we
 355     * we defer completion of removal in such cases to the reset() hook.
 356     */
 357    if (drc->type == SPAPR_DR_CONNECTOR_TYPE_PCI) {
 358        drc->isolation_state = SPAPR_DR_ISOLATION_STATE_UNISOLATED;
 359    }
 360    drc->indicator_state = SPAPR_DR_INDICATOR_STATE_ACTIVE;
 361
 362    drc->dev = d;
 363    drc->fdt = fdt;
 364    drc->fdt_start_offset = fdt_start_offset;
 365    drc->configured = coldplug;
 366    /* 'logical' DR resources such as memory/cpus are in some cases treated
 367     * as a pool of resources from which the guest is free to choose from
 368     * based on only a count. for resources that can be assigned in this
 369     * fashion, we must assume the resource is signalled immediately
 370     * since a single hotplug request might make an arbitrary number of
 371     * such attached resources available to the guest, as opposed to
 372     * 'physical' DR resources such as PCI where each device/resource is
 373     * signalled individually.
 374     */
 375    drc->signalled = (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI)
 376                     ? true : coldplug;
 377
 378    if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI) {
 379        drc->awaiting_allocation = true;
 380    }
 381
 382    object_property_add_link(OBJECT(drc), "device",
 383                             object_get_typename(OBJECT(drc->dev)),
 384                             (Object **)(&drc->dev),
 385                             NULL, 0, NULL);
 386}
 387
 388static void detach(sPAPRDRConnector *drc, DeviceState *d,
 389                   spapr_drc_detach_cb *detach_cb,
 390                   void *detach_cb_opaque, Error **errp)
 391{
 392    DPRINTFN("drc: %x, detach", get_index(drc));
 393
 394    drc->detach_cb = detach_cb;
 395    drc->detach_cb_opaque = detach_cb_opaque;
 396
 397    /* if we've signalled device presence to the guest, or if the guest
 398     * has gone ahead and configured the device (via manually-executed
 399     * device add via drmgr in guest, namely), we need to wait
 400     * for the guest to quiesce the device before completing detach.
 401     * Otherwise, we can assume the guest hasn't seen it and complete the
 402     * detach immediately. Note that there is a small race window
 403     * just before, or during, configuration, which is this context
 404     * refers mainly to fetching the device tree via RTAS.
 405     * During this window the device access will be arbitrated by
 406     * associated DRC, which will simply fail the RTAS calls as invalid.
 407     * This is recoverable within guest and current implementations of
 408     * drmgr should be able to cope.
 409     */
 410    if (!drc->signalled && !drc->configured) {
 411        /* if the guest hasn't seen the device we can't rely on it to
 412         * set it back to an isolated state via RTAS, so do it here manually
 413         */
 414        drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED;
 415    }
 416
 417    if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {
 418        DPRINTFN("awaiting transition to isolated state before removal");
 419        drc->awaiting_release = true;
 420        return;
 421    }
 422
 423    if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI &&
 424        drc->allocation_state != SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
 425        DPRINTFN("awaiting transition to unusable state before removal");
 426        drc->awaiting_release = true;
 427        return;
 428    }
 429
 430    if (drc->awaiting_allocation) {
 431        drc->awaiting_release = true;
 432        DPRINTFN("awaiting allocation to complete before removal");
 433        return;
 434    }
 435
 436    drc->indicator_state = SPAPR_DR_INDICATOR_STATE_INACTIVE;
 437
 438    if (drc->detach_cb) {
 439        drc->detach_cb(drc->dev, drc->detach_cb_opaque);
 440    }
 441
 442    drc->awaiting_release = false;
 443    g_free(drc->fdt);
 444    drc->fdt = NULL;
 445    drc->fdt_start_offset = 0;
 446    object_property_del(OBJECT(drc), "device", NULL);
 447    drc->dev = NULL;
 448    drc->detach_cb = NULL;
 449    drc->detach_cb_opaque = NULL;
 450}
 451
 452static bool release_pending(sPAPRDRConnector *drc)
 453{
 454    return drc->awaiting_release;
 455}
 456
 457static void reset(DeviceState *d)
 458{
 459    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
 460    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 461    sPAPRDREntitySense state;
 462
 463    DPRINTFN("drc reset: %x", drck->get_index(drc));
 464    /* immediately upon reset we can safely assume DRCs whose devices
 465     * are pending removal can be safely removed, and that they will
 466     * subsequently be left in an ISOLATED state. move the DRC to this
 467     * state in these cases (which will in turn complete any pending
 468     * device removals)
 469     */
 470    if (drc->awaiting_release) {
 471        drck->set_isolation_state(drc, SPAPR_DR_ISOLATION_STATE_ISOLATED);
 472        /* generally this should also finalize the removal, but if the device
 473         * hasn't yet been configured we normally defer removal under the
 474         * assumption that this transition is taking place as part of device
 475         * configuration. so check if we're still waiting after this, and
 476         * force removal if we are
 477         */
 478        if (drc->awaiting_release) {
 479            drck->detach(drc, DEVICE(drc->dev), drc->detach_cb,
 480                         drc->detach_cb_opaque, NULL);
 481        }
 482
 483        /* non-PCI devices may be awaiting a transition to UNUSABLE */
 484        if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI &&
 485            drc->awaiting_release) {
 486            drck->set_allocation_state(drc, SPAPR_DR_ALLOCATION_STATE_UNUSABLE);
 487        }
 488    }
 489
 490    drck->entity_sense(drc, &state);
 491    if (state == SPAPR_DR_ENTITY_SENSE_PRESENT) {
 492        drck->set_signalled(drc);
 493    }
 494}
 495
 496static void realize(DeviceState *d, Error **errp)
 497{
 498    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
 499    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 500    Object *root_container;
 501    char link_name[256];
 502    gchar *child_name;
 503    Error *err = NULL;
 504
 505    DPRINTFN("drc realize: %x", drck->get_index(drc));
 506    /* NOTE: we do this as part of realize/unrealize due to the fact
 507     * that the guest will communicate with the DRC via RTAS calls
 508     * referencing the global DRC index. By unlinking the DRC
 509     * from DRC_CONTAINER_PATH/<drc_index> we effectively make it
 510     * inaccessible by the guest, since lookups rely on this path
 511     * existing in the composition tree
 512     */
 513    root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
 514    snprintf(link_name, sizeof(link_name), "%x", drck->get_index(drc));
 515    child_name = object_get_canonical_path_component(OBJECT(drc));
 516    DPRINTFN("drc child name: %s", child_name);
 517    object_property_add_alias(root_container, link_name,
 518                              drc->owner, child_name, &err);
 519    if (err) {
 520        error_report_err(err);
 521        object_unref(OBJECT(drc));
 522    }
 523    g_free(child_name);
 524    DPRINTFN("drc realize complete");
 525}
 526
 527static void unrealize(DeviceState *d, Error **errp)
 528{
 529    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
 530    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 531    Object *root_container;
 532    char name[256];
 533    Error *err = NULL;
 534
 535    DPRINTFN("drc unrealize: %x", drck->get_index(drc));
 536    root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
 537    snprintf(name, sizeof(name), "%x", drck->get_index(drc));
 538    object_property_del(root_container, name, &err);
 539    if (err) {
 540        error_report_err(err);
 541        object_unref(OBJECT(drc));
 542    }
 543}
 544
 545sPAPRDRConnector *spapr_dr_connector_new(Object *owner,
 546                                         sPAPRDRConnectorType type,
 547                                         uint32_t id)
 548{
 549    sPAPRDRConnector *drc =
 550        SPAPR_DR_CONNECTOR(object_new(TYPE_SPAPR_DR_CONNECTOR));
 551    char *prop_name;
 552
 553    g_assert(type);
 554
 555    drc->type = type;
 556    drc->id = id;
 557    drc->owner = owner;
 558    prop_name = g_strdup_printf("dr-connector[%"PRIu32"]", get_index(drc));
 559    object_property_add_child(owner, prop_name, OBJECT(drc), NULL);
 560    object_property_set_bool(OBJECT(drc), true, "realized", NULL);
 561    g_free(prop_name);
 562
 563    /* human-readable name for a DRC to encode into the DT
 564     * description. this is mainly only used within a guest in place
 565     * of the unique DRC index.
 566     *
 567     * in the case of VIO/PCI devices, it corresponds to a
 568     * "location code" that maps a logical device/function (DRC index)
 569     * to a physical (or virtual in the case of VIO) location in the
 570     * system by chaining together the "location label" for each
 571     * encapsulating component.
 572     *
 573     * since this is more to do with diagnosing physical hardware
 574     * issues than guest compatibility, we choose location codes/DRC
 575     * names that adhere to the documented format, but avoid encoding
 576     * the entire topology information into the label/code, instead
 577     * just using the location codes based on the labels for the
 578     * endpoints (VIO/PCI adaptor connectors), which is basically
 579     * just "C" followed by an integer ID.
 580     *
 581     * DRC names as documented by PAPR+ v2.7, 13.5.2.4
 582     * location codes as documented by PAPR+ v2.7, 12.3.1.5
 583     */
 584    switch (drc->type) {
 585    case SPAPR_DR_CONNECTOR_TYPE_CPU:
 586        drc->name = g_strdup_printf("CPU %d", id);
 587        break;
 588    case SPAPR_DR_CONNECTOR_TYPE_PHB:
 589        drc->name = g_strdup_printf("PHB %d", id);
 590        break;
 591    case SPAPR_DR_CONNECTOR_TYPE_VIO:
 592    case SPAPR_DR_CONNECTOR_TYPE_PCI:
 593        drc->name = g_strdup_printf("C%d", id);
 594        break;
 595    case SPAPR_DR_CONNECTOR_TYPE_LMB:
 596        drc->name = g_strdup_printf("LMB %d", id);
 597        break;
 598    default:
 599        g_assert(false);
 600    }
 601
 602    /* PCI slot always start in a USABLE state, and stay there */
 603    if (drc->type == SPAPR_DR_CONNECTOR_TYPE_PCI) {
 604        drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_USABLE;
 605    }
 606
 607    return drc;
 608}
 609
 610static void spapr_dr_connector_instance_init(Object *obj)
 611{
 612    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
 613
 614    object_property_add_uint32_ptr(obj, "isolation-state",
 615                                   &drc->isolation_state, NULL);
 616    object_property_add_uint32_ptr(obj, "indicator-state",
 617                                   &drc->indicator_state, NULL);
 618    object_property_add_uint32_ptr(obj, "allocation-state",
 619                                   &drc->allocation_state, NULL);
 620    object_property_add_uint32_ptr(obj, "id", &drc->id, NULL);
 621    object_property_add(obj, "index", "uint32", prop_get_index,
 622                        NULL, NULL, NULL, NULL);
 623    object_property_add(obj, "connector_type", "uint32", prop_get_type,
 624                        NULL, NULL, NULL, NULL);
 625    object_property_add_str(obj, "name", prop_get_name, NULL, NULL);
 626    object_property_add(obj, "entity-sense", "uint32", prop_get_entity_sense,
 627                        NULL, NULL, NULL, NULL);
 628    object_property_add(obj, "fdt", "struct", prop_get_fdt,
 629                        NULL, NULL, NULL, NULL);
 630}
 631
 632static void spapr_dr_connector_class_init(ObjectClass *k, void *data)
 633{
 634    DeviceClass *dk = DEVICE_CLASS(k);
 635    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
 636
 637    dk->reset = reset;
 638    dk->realize = realize;
 639    dk->unrealize = unrealize;
 640    drck->set_isolation_state = set_isolation_state;
 641    drck->set_indicator_state = set_indicator_state;
 642    drck->set_allocation_state = set_allocation_state;
 643    drck->get_index = get_index;
 644    drck->get_type = get_type;
 645    drck->get_name = get_name;
 646    drck->get_fdt = get_fdt;
 647    drck->set_configured = set_configured;
 648    drck->entity_sense = entity_sense;
 649    drck->attach = attach;
 650    drck->detach = detach;
 651    drck->release_pending = release_pending;
 652    drck->set_signalled = set_signalled;
 653    /*
 654     * Reason: it crashes FIXME find and document the real reason
 655     */
 656    dk->cannot_instantiate_with_device_add_yet = true;
 657}
 658
 659static const TypeInfo spapr_dr_connector_info = {
 660    .name          = TYPE_SPAPR_DR_CONNECTOR,
 661    .parent        = TYPE_DEVICE,
 662    .instance_size = sizeof(sPAPRDRConnector),
 663    .instance_init = spapr_dr_connector_instance_init,
 664    .class_size    = sizeof(sPAPRDRConnectorClass),
 665    .class_init    = spapr_dr_connector_class_init,
 666};
 667
 668static void spapr_drc_register_types(void)
 669{
 670    type_register_static(&spapr_dr_connector_info);
 671}
 672
 673type_init(spapr_drc_register_types)
 674
 675/* helper functions for external users */
 676
 677sPAPRDRConnector *spapr_dr_connector_by_index(uint32_t index)
 678{
 679    Object *obj;
 680    char name[256];
 681
 682    snprintf(name, sizeof(name), "%s/%x", DRC_CONTAINER_PATH, index);
 683    obj = object_resolve_path(name, NULL);
 684
 685    return !obj ? NULL : SPAPR_DR_CONNECTOR(obj);
 686}
 687
 688sPAPRDRConnector *spapr_dr_connector_by_id(sPAPRDRConnectorType type,
 689                                           uint32_t id)
 690{
 691    return spapr_dr_connector_by_index(
 692            (get_type_shift(type) << DRC_INDEX_TYPE_SHIFT) |
 693            (id & DRC_INDEX_ID_MASK));
 694}
 695
 696/* generate a string the describes the DRC to encode into the
 697 * device tree.
 698 *
 699 * as documented by PAPR+ v2.7, 13.5.2.6 and C.6.1
 700 */
 701static const char *spapr_drc_get_type_str(sPAPRDRConnectorType type)
 702{
 703    switch (type) {
 704    case SPAPR_DR_CONNECTOR_TYPE_CPU:
 705        return "CPU";
 706    case SPAPR_DR_CONNECTOR_TYPE_PHB:
 707        return "PHB";
 708    case SPAPR_DR_CONNECTOR_TYPE_VIO:
 709        return "SLOT";
 710    case SPAPR_DR_CONNECTOR_TYPE_PCI:
 711        return "28";
 712    case SPAPR_DR_CONNECTOR_TYPE_LMB:
 713        return "MEM";
 714    default:
 715        g_assert(false);
 716    }
 717
 718    return NULL;
 719}
 720
 721/**
 722 * spapr_drc_populate_dt
 723 *
 724 * @fdt: libfdt device tree
 725 * @path: path in the DT to generate properties
 726 * @owner: parent Object/DeviceState for which to generate DRC
 727 *         descriptions for
 728 * @drc_type_mask: mask of sPAPRDRConnectorType values corresponding
 729 *   to the types of DRCs to generate entries for
 730 *
 731 * generate OF properties to describe DRC topology/indices to guests
 732 *
 733 * as documented in PAPR+ v2.1, 13.5.2
 734 */
 735int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
 736                          uint32_t drc_type_mask)
 737{
 738    Object *root_container;
 739    ObjectProperty *prop;
 740    ObjectPropertyIterator iter;
 741    uint32_t drc_count = 0;
 742    GArray *drc_indexes, *drc_power_domains;
 743    GString *drc_names, *drc_types;
 744    int ret;
 745
 746    /* the first entry of each properties is a 32-bit integer encoding
 747     * the number of elements in the array. we won't know this until
 748     * we complete the iteration through all the matching DRCs, but
 749     * reserve the space now and set the offsets accordingly so we
 750     * can fill them in later.
 751     */
 752    drc_indexes = g_array_new(false, true, sizeof(uint32_t));
 753    drc_indexes = g_array_set_size(drc_indexes, 1);
 754    drc_power_domains = g_array_new(false, true, sizeof(uint32_t));
 755    drc_power_domains = g_array_set_size(drc_power_domains, 1);
 756    drc_names = g_string_set_size(g_string_new(NULL), sizeof(uint32_t));
 757    drc_types = g_string_set_size(g_string_new(NULL), sizeof(uint32_t));
 758
 759    /* aliases for all DRConnector objects will be rooted in QOM
 760     * composition tree at DRC_CONTAINER_PATH
 761     */
 762    root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
 763
 764    object_property_iter_init(&iter, root_container);
 765    while ((prop = object_property_iter_next(&iter))) {
 766        Object *obj;
 767        sPAPRDRConnector *drc;
 768        sPAPRDRConnectorClass *drck;
 769        uint32_t drc_index, drc_power_domain;
 770
 771        if (!strstart(prop->type, "link<", NULL)) {
 772            continue;
 773        }
 774
 775        obj = object_property_get_link(root_container, prop->name, NULL);
 776        drc = SPAPR_DR_CONNECTOR(obj);
 777        drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 778
 779        if (owner && (drc->owner != owner)) {
 780            continue;
 781        }
 782
 783        if ((drc->type & drc_type_mask) == 0) {
 784            continue;
 785        }
 786
 787        drc_count++;
 788
 789        /* ibm,drc-indexes */
 790        drc_index = cpu_to_be32(drck->get_index(drc));
 791        g_array_append_val(drc_indexes, drc_index);
 792
 793        /* ibm,drc-power-domains */
 794        drc_power_domain = cpu_to_be32(-1);
 795        g_array_append_val(drc_power_domains, drc_power_domain);
 796
 797        /* ibm,drc-names */
 798        drc_names = g_string_append(drc_names, drck->get_name(drc));
 799        drc_names = g_string_insert_len(drc_names, -1, "\0", 1);
 800
 801        /* ibm,drc-types */
 802        drc_types = g_string_append(drc_types,
 803                                    spapr_drc_get_type_str(drc->type));
 804        drc_types = g_string_insert_len(drc_types, -1, "\0", 1);
 805    }
 806
 807    /* now write the drc count into the space we reserved at the
 808     * beginning of the arrays previously
 809     */
 810    *(uint32_t *)drc_indexes->data = cpu_to_be32(drc_count);
 811    *(uint32_t *)drc_power_domains->data = cpu_to_be32(drc_count);
 812    *(uint32_t *)drc_names->str = cpu_to_be32(drc_count);
 813    *(uint32_t *)drc_types->str = cpu_to_be32(drc_count);
 814
 815    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-indexes",
 816                      drc_indexes->data,
 817                      drc_indexes->len * sizeof(uint32_t));
 818    if (ret) {
 819        fprintf(stderr, "Couldn't create ibm,drc-indexes property\n");
 820        goto out;
 821    }
 822
 823    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-power-domains",
 824                      drc_power_domains->data,
 825                      drc_power_domains->len * sizeof(uint32_t));
 826    if (ret) {
 827        fprintf(stderr, "Couldn't finalize ibm,drc-power-domains property\n");
 828        goto out;
 829    }
 830
 831    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-names",
 832                      drc_names->str, drc_names->len);
 833    if (ret) {
 834        fprintf(stderr, "Couldn't finalize ibm,drc-names property\n");
 835        goto out;
 836    }
 837
 838    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-types",
 839                      drc_types->str, drc_types->len);
 840    if (ret) {
 841        fprintf(stderr, "Couldn't finalize ibm,drc-types property\n");
 842        goto out;
 843    }
 844
 845out:
 846    g_array_free(drc_indexes, true);
 847    g_array_free(drc_power_domains, true);
 848    g_string_free(drc_names, true);
 849    g_string_free(drc_types, true);
 850
 851    return ret;
 852}
 853