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