xref: /openbmc/qemu/hw/ppc/spapr_drc.c (revision f3ced3c5)
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 "hw/pci-host/spapr.h" /* spapr_phb_remove_pci_device_cb callback */
24 #include "trace.h"
25 
26 #define DRC_CONTAINER_PATH "/dr-connector"
27 #define DRC_INDEX_TYPE_SHIFT 28
28 #define DRC_INDEX_ID_MASK ((1ULL << DRC_INDEX_TYPE_SHIFT) - 1)
29 
30 sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc)
31 {
32     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
33 
34     return 1 << drck->typeshift;
35 }
36 
37 uint32_t spapr_drc_index(sPAPRDRConnector *drc)
38 {
39     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
40 
41     /* no set format for a drc index: it only needs to be globally
42      * unique. this is how we encode the DRC type on bare-metal
43      * however, so might as well do that here
44      */
45     return (drck->typeshift << DRC_INDEX_TYPE_SHIFT)
46         | (drc->id & DRC_INDEX_ID_MASK);
47 }
48 
49 static uint32_t drc_isolate_physical(sPAPRDRConnector *drc)
50 {
51     /* if the guest is configuring a device attached to this DRC, we
52      * should reset the configuration state at this point since it may
53      * no longer be reliable (guest released device and needs to start
54      * over, or unplug occurred so the FDT is no longer valid)
55      */
56     g_free(drc->ccs);
57     drc->ccs = NULL;
58 
59     drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED;
60 
61     /* if we're awaiting release, but still in an unconfigured state,
62      * it's likely the guest is still in the process of configuring
63      * the device and is transitioning the devices to an ISOLATED
64      * state as a part of that process. so we only complete the
65      * removal when this transition happens for a device in a
66      * configured state, as suggested by the state diagram from PAPR+
67      * 2.7, 13.4
68      */
69     if (drc->awaiting_release) {
70         uint32_t drc_index = spapr_drc_index(drc);
71         if (drc->configured) {
72             trace_spapr_drc_set_isolation_state_finalizing(drc_index);
73             spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
74         } else {
75             trace_spapr_drc_set_isolation_state_deferring(drc_index);
76         }
77     }
78     drc->configured = false;
79 
80     return RTAS_OUT_SUCCESS;
81 }
82 
83 static uint32_t drc_unisolate_physical(sPAPRDRConnector *drc)
84 {
85     /* cannot unisolate a non-existent resource, and, or resources
86      * which are in an 'UNUSABLE' allocation state. (PAPR 2.7,
87      * 13.5.3.5)
88      */
89     if (!drc->dev) {
90         return RTAS_OUT_NO_SUCH_INDICATOR;
91     }
92 
93     drc->isolation_state = SPAPR_DR_ISOLATION_STATE_UNISOLATED;
94 
95     return RTAS_OUT_SUCCESS;
96 }
97 
98 static uint32_t drc_isolate_logical(sPAPRDRConnector *drc)
99 {
100     /* if the guest is configuring a device attached to this DRC, we
101      * should reset the configuration state at this point since it may
102      * no longer be reliable (guest released device and needs to start
103      * over, or unplug occurred so the FDT is no longer valid)
104      */
105     g_free(drc->ccs);
106     drc->ccs = NULL;
107 
108     /*
109      * Fail any requests to ISOLATE the LMB DRC if this LMB doesn't
110      * belong to a DIMM device that is marked for removal.
111      *
112      * Currently the guest userspace tool drmgr that drives the memory
113      * hotplug/unplug will just try to remove a set of 'removable' LMBs
114      * in response to a hot unplug request that is based on drc-count.
115      * If the LMB being removed doesn't belong to a DIMM device that is
116      * actually being unplugged, fail the isolation request here.
117      */
118     if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB
119         && !drc->awaiting_release) {
120         return RTAS_OUT_HW_ERROR;
121     }
122 
123     drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED;
124 
125     /* if we're awaiting release, but still in an unconfigured state,
126      * it's likely the guest is still in the process of configuring
127      * the device and is transitioning the devices to an ISOLATED
128      * state as a part of that process. so we only complete the
129      * removal when this transition happens for a device in a
130      * configured state, as suggested by the state diagram from PAPR+
131      * 2.7, 13.4
132      */
133     if (drc->awaiting_release) {
134         uint32_t drc_index = spapr_drc_index(drc);
135         if (drc->configured) {
136             trace_spapr_drc_set_isolation_state_finalizing(drc_index);
137             spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
138         } else {
139             trace_spapr_drc_set_isolation_state_deferring(drc_index);
140         }
141     }
142     drc->configured = false;
143 
144     return RTAS_OUT_SUCCESS;
145 }
146 
147 static uint32_t drc_unisolate_logical(sPAPRDRConnector *drc)
148 {
149     /* cannot unisolate a non-existent resource, and, or resources
150      * which are in an 'UNUSABLE' allocation state. (PAPR 2.7,
151      * 13.5.3.5)
152      */
153     if (!drc->dev ||
154         drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
155         return RTAS_OUT_NO_SUCH_INDICATOR;
156     }
157 
158     drc->isolation_state = SPAPR_DR_ISOLATION_STATE_UNISOLATED;
159 
160     return RTAS_OUT_SUCCESS;
161 }
162 
163 static uint32_t drc_set_usable(sPAPRDRConnector *drc)
164 {
165     /* if there's no resource/device associated with the DRC, there's
166      * no way for us to put it in an allocation state consistent with
167      * being 'USABLE'. PAPR 2.7, 13.5.3.4 documents that this should
168      * result in an RTAS return code of -3 / "no such indicator"
169      */
170     if (!drc->dev) {
171         return RTAS_OUT_NO_SUCH_INDICATOR;
172     }
173     if (drc->awaiting_release && drc->awaiting_allocation) {
174         /* kernel is acknowledging a previous hotplug event
175          * while we are already removing it.
176          * it's safe to ignore awaiting_allocation here since we know the
177          * situation is predicated on the guest either already having done
178          * so (boot-time hotplug), or never being able to acquire in the
179          * first place (hotplug followed by immediate unplug).
180          */
181         return RTAS_OUT_NO_SUCH_INDICATOR;
182     }
183 
184     drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_USABLE;
185     drc->awaiting_allocation = false;
186 
187     return RTAS_OUT_SUCCESS;
188 }
189 
190 static uint32_t drc_set_unusable(sPAPRDRConnector *drc)
191 {
192     drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_UNUSABLE;
193     if (drc->awaiting_release) {
194         uint32_t drc_index = spapr_drc_index(drc);
195         trace_spapr_drc_set_allocation_state_finalizing(drc_index);
196         spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
197     }
198 
199     return RTAS_OUT_SUCCESS;
200 }
201 
202 static const char *spapr_drc_name(sPAPRDRConnector *drc)
203 {
204     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
205 
206     /* human-readable name for a DRC to encode into the DT
207      * description. this is mainly only used within a guest in place
208      * of the unique DRC index.
209      *
210      * in the case of VIO/PCI devices, it corresponds to a "location
211      * code" that maps a logical device/function (DRC index) to a
212      * physical (or virtual in the case of VIO) location in the system
213      * by chaining together the "location label" for each
214      * encapsulating component.
215      *
216      * since this is more to do with diagnosing physical hardware
217      * issues than guest compatibility, we choose location codes/DRC
218      * names that adhere to the documented format, but avoid encoding
219      * the entire topology information into the label/code, instead
220      * just using the location codes based on the labels for the
221      * endpoints (VIO/PCI adaptor connectors), which is basically just
222      * "C" followed by an integer ID.
223      *
224      * DRC names as documented by PAPR+ v2.7, 13.5.2.4
225      * location codes as documented by PAPR+ v2.7, 12.3.1.5
226      */
227     return g_strdup_printf("%s%d", drck->drc_name_prefix, drc->id);
228 }
229 
230 /*
231  * dr-entity-sense sensor value
232  * returned via get-sensor-state RTAS calls
233  * as expected by state diagram in PAPR+ 2.7, 13.4
234  * based on the current allocation/indicator/power states
235  * for the DR connector.
236  */
237 static sPAPRDREntitySense physical_entity_sense(sPAPRDRConnector *drc)
238 {
239     /* this assumes all PCI devices are assigned to a 'live insertion'
240      * power domain, where QEMU manages power state automatically as
241      * opposed to the guest. present, non-PCI resources are unaffected
242      * by power state.
243      */
244     return drc->dev ? SPAPR_DR_ENTITY_SENSE_PRESENT
245         : SPAPR_DR_ENTITY_SENSE_EMPTY;
246 }
247 
248 static sPAPRDREntitySense logical_entity_sense(sPAPRDRConnector *drc)
249 {
250     if (drc->dev
251         && (drc->allocation_state != SPAPR_DR_ALLOCATION_STATE_UNUSABLE)) {
252         return SPAPR_DR_ENTITY_SENSE_PRESENT;
253     } else {
254         return SPAPR_DR_ENTITY_SENSE_UNUSABLE;
255     }
256 }
257 
258 static void prop_get_index(Object *obj, Visitor *v, const char *name,
259                            void *opaque, Error **errp)
260 {
261     sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
262     uint32_t value = spapr_drc_index(drc);
263     visit_type_uint32(v, name, &value, errp);
264 }
265 
266 static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
267                          void *opaque, Error **errp)
268 {
269     sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
270     Error *err = NULL;
271     int fdt_offset_next, fdt_offset, fdt_depth;
272     void *fdt;
273 
274     if (!drc->fdt) {
275         visit_type_null(v, NULL, errp);
276         return;
277     }
278 
279     fdt = drc->fdt;
280     fdt_offset = drc->fdt_start_offset;
281     fdt_depth = 0;
282 
283     do {
284         const char *name = NULL;
285         const struct fdt_property *prop = NULL;
286         int prop_len = 0, name_len = 0;
287         uint32_t tag;
288 
289         tag = fdt_next_tag(fdt, fdt_offset, &fdt_offset_next);
290         switch (tag) {
291         case FDT_BEGIN_NODE:
292             fdt_depth++;
293             name = fdt_get_name(fdt, fdt_offset, &name_len);
294             visit_start_struct(v, name, NULL, 0, &err);
295             if (err) {
296                 error_propagate(errp, err);
297                 return;
298             }
299             break;
300         case FDT_END_NODE:
301             /* shouldn't ever see an FDT_END_NODE before FDT_BEGIN_NODE */
302             g_assert(fdt_depth > 0);
303             visit_check_struct(v, &err);
304             visit_end_struct(v, NULL);
305             if (err) {
306                 error_propagate(errp, err);
307                 return;
308             }
309             fdt_depth--;
310             break;
311         case FDT_PROP: {
312             int i;
313             prop = fdt_get_property_by_offset(fdt, fdt_offset, &prop_len);
314             name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
315             visit_start_list(v, name, NULL, 0, &err);
316             if (err) {
317                 error_propagate(errp, err);
318                 return;
319             }
320             for (i = 0; i < prop_len; i++) {
321                 visit_type_uint8(v, NULL, (uint8_t *)&prop->data[i], &err);
322                 if (err) {
323                     error_propagate(errp, err);
324                     return;
325                 }
326             }
327             visit_check_list(v, &err);
328             visit_end_list(v, NULL);
329             if (err) {
330                 error_propagate(errp, err);
331                 return;
332             }
333             break;
334         }
335         default:
336             error_setg(&error_abort, "device FDT in unexpected state: %d", tag);
337         }
338         fdt_offset = fdt_offset_next;
339     } while (fdt_depth != 0);
340 }
341 
342 void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
343                       int fdt_start_offset, bool coldplug, Error **errp)
344 {
345     trace_spapr_drc_attach(spapr_drc_index(drc));
346 
347     if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {
348         error_setg(errp, "an attached device is still awaiting release");
349         return;
350     }
351     if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_PCI) {
352         g_assert(drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE);
353     }
354     g_assert(fdt || coldplug);
355 
356     drc->dr_indicator = SPAPR_DR_INDICATOR_ACTIVE;
357 
358     drc->dev = d;
359     drc->fdt = fdt;
360     drc->fdt_start_offset = fdt_start_offset;
361     drc->configured = coldplug;
362 
363     if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) {
364         drc->awaiting_allocation = true;
365     }
366 
367     object_property_add_link(OBJECT(drc), "device",
368                              object_get_typename(OBJECT(drc->dev)),
369                              (Object **)(&drc->dev),
370                              NULL, 0, NULL);
371 }
372 
373 static void spapr_drc_release(sPAPRDRConnector *drc)
374 {
375     drc->dr_indicator = SPAPR_DR_INDICATOR_INACTIVE;
376 
377     /* Calling release callbacks based on spapr_drc_type(drc). */
378     switch (spapr_drc_type(drc)) {
379     case SPAPR_DR_CONNECTOR_TYPE_CPU:
380         spapr_core_release(drc->dev);
381         break;
382     case SPAPR_DR_CONNECTOR_TYPE_PCI:
383         spapr_phb_remove_pci_device_cb(drc->dev);
384         break;
385     case SPAPR_DR_CONNECTOR_TYPE_LMB:
386         spapr_lmb_release(drc->dev);
387         break;
388     case SPAPR_DR_CONNECTOR_TYPE_PHB:
389     case SPAPR_DR_CONNECTOR_TYPE_VIO:
390     default:
391         g_assert(false);
392     }
393 
394     drc->awaiting_release = false;
395     g_free(drc->fdt);
396     drc->fdt = NULL;
397     drc->fdt_start_offset = 0;
398     object_property_del(OBJECT(drc), "device", NULL);
399     drc->dev = NULL;
400 }
401 
402 void spapr_drc_detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
403 {
404     trace_spapr_drc_detach(spapr_drc_index(drc));
405 
406     if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {
407         trace_spapr_drc_awaiting_isolated(spapr_drc_index(drc));
408         drc->awaiting_release = true;
409         return;
410     }
411 
412     if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI &&
413         drc->allocation_state != SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
414         trace_spapr_drc_awaiting_unusable(spapr_drc_index(drc));
415         drc->awaiting_release = true;
416         return;
417     }
418 
419     if (drc->awaiting_allocation) {
420         drc->awaiting_release = true;
421         trace_spapr_drc_awaiting_allocation(spapr_drc_index(drc));
422         return;
423     }
424 
425     spapr_drc_release(drc);
426 }
427 
428 static bool release_pending(sPAPRDRConnector *drc)
429 {
430     return drc->awaiting_release;
431 }
432 
433 static void reset(DeviceState *d)
434 {
435     sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
436 
437     trace_spapr_drc_reset(spapr_drc_index(drc));
438 
439     g_free(drc->ccs);
440     drc->ccs = NULL;
441 
442     /* immediately upon reset we can safely assume DRCs whose devices
443      * are pending removal can be safely removed.
444      */
445     if (drc->awaiting_release) {
446         spapr_drc_release(drc);
447     }
448 
449     drc->awaiting_allocation = false;
450 
451     if (drc->dev) {
452         /* A device present at reset is coldplugged */
453         drc->isolation_state = SPAPR_DR_ISOLATION_STATE_UNISOLATED;
454         if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) {
455             drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_USABLE;
456         }
457     } else {
458         /* Otherwise device is absent, but might be hotplugged */
459         drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED;
460         if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) {
461             drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_UNUSABLE;
462         }
463     }
464 }
465 
466 static bool spapr_drc_needed(void *opaque)
467 {
468     sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
469     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
470     bool rc = false;
471     sPAPRDREntitySense value = drck->dr_entity_sense(drc);
472 
473     /* If no dev is plugged in there is no need to migrate the DRC state */
474     if (value != SPAPR_DR_ENTITY_SENSE_PRESENT) {
475         return false;
476     }
477 
478     /*
479      * If there is dev plugged in, we need to migrate the DRC state when
480      * it is different from cold-plugged state
481      */
482     switch (spapr_drc_type(drc)) {
483     case SPAPR_DR_CONNECTOR_TYPE_PCI:
484     case SPAPR_DR_CONNECTOR_TYPE_CPU:
485     case SPAPR_DR_CONNECTOR_TYPE_LMB:
486         rc = !((drc->isolation_state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) &&
487                (drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE) &&
488                drc->configured && !drc->awaiting_release);
489         break;
490     case SPAPR_DR_CONNECTOR_TYPE_PHB:
491     case SPAPR_DR_CONNECTOR_TYPE_VIO:
492     default:
493         g_assert_not_reached();
494     }
495     return rc;
496 }
497 
498 static const VMStateDescription vmstate_spapr_drc = {
499     .name = "spapr_drc",
500     .version_id = 1,
501     .minimum_version_id = 1,
502     .needed = spapr_drc_needed,
503     .fields  = (VMStateField []) {
504         VMSTATE_UINT32(isolation_state, sPAPRDRConnector),
505         VMSTATE_UINT32(allocation_state, sPAPRDRConnector),
506         VMSTATE_UINT32(dr_indicator, sPAPRDRConnector),
507         VMSTATE_BOOL(configured, sPAPRDRConnector),
508         VMSTATE_BOOL(awaiting_release, sPAPRDRConnector),
509         VMSTATE_BOOL(awaiting_allocation, sPAPRDRConnector),
510         VMSTATE_END_OF_LIST()
511     }
512 };
513 
514 static void realize(DeviceState *d, Error **errp)
515 {
516     sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
517     Object *root_container;
518     char link_name[256];
519     gchar *child_name;
520     Error *err = NULL;
521 
522     trace_spapr_drc_realize(spapr_drc_index(drc));
523     /* NOTE: we do this as part of realize/unrealize due to the fact
524      * that the guest will communicate with the DRC via RTAS calls
525      * referencing the global DRC index. By unlinking the DRC
526      * from DRC_CONTAINER_PATH/<drc_index> we effectively make it
527      * inaccessible by the guest, since lookups rely on this path
528      * existing in the composition tree
529      */
530     root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
531     snprintf(link_name, sizeof(link_name), "%x", spapr_drc_index(drc));
532     child_name = object_get_canonical_path_component(OBJECT(drc));
533     trace_spapr_drc_realize_child(spapr_drc_index(drc), child_name);
534     object_property_add_alias(root_container, link_name,
535                               drc->owner, child_name, &err);
536     if (err) {
537         error_report_err(err);
538         object_unref(OBJECT(drc));
539     }
540     g_free(child_name);
541     vmstate_register(DEVICE(drc), spapr_drc_index(drc), &vmstate_spapr_drc,
542                      drc);
543     trace_spapr_drc_realize_complete(spapr_drc_index(drc));
544 }
545 
546 static void unrealize(DeviceState *d, Error **errp)
547 {
548     sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
549     Object *root_container;
550     char name[256];
551     Error *err = NULL;
552 
553     trace_spapr_drc_unrealize(spapr_drc_index(drc));
554     root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
555     snprintf(name, sizeof(name), "%x", spapr_drc_index(drc));
556     object_property_del(root_container, name, &err);
557     if (err) {
558         error_report_err(err);
559         object_unref(OBJECT(drc));
560     }
561 }
562 
563 sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type,
564                                          uint32_t id)
565 {
566     sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(object_new(type));
567     char *prop_name;
568 
569     drc->id = id;
570     drc->owner = owner;
571     prop_name = g_strdup_printf("dr-connector[%"PRIu32"]",
572                                 spapr_drc_index(drc));
573     object_property_add_child(owner, prop_name, OBJECT(drc), NULL);
574     object_property_set_bool(OBJECT(drc), true, "realized", NULL);
575     g_free(prop_name);
576 
577     /* PCI slot always start in a USABLE state, and stay there */
578     if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_PCI) {
579         drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_USABLE;
580     }
581 
582     return drc;
583 }
584 
585 static void spapr_dr_connector_instance_init(Object *obj)
586 {
587     sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
588 
589     object_property_add_uint32_ptr(obj, "id", &drc->id, NULL);
590     object_property_add(obj, "index", "uint32", prop_get_index,
591                         NULL, NULL, NULL, NULL);
592     object_property_add(obj, "fdt", "struct", prop_get_fdt,
593                         NULL, NULL, NULL, NULL);
594 }
595 
596 static void spapr_dr_connector_class_init(ObjectClass *k, void *data)
597 {
598     DeviceClass *dk = DEVICE_CLASS(k);
599     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
600 
601     dk->reset = reset;
602     dk->realize = realize;
603     dk->unrealize = unrealize;
604     drck->release_pending = release_pending;
605     /*
606      * Reason: it crashes FIXME find and document the real reason
607      */
608     dk->user_creatable = false;
609 }
610 
611 static void spapr_drc_physical_class_init(ObjectClass *k, void *data)
612 {
613     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
614 
615     drck->dr_entity_sense = physical_entity_sense;
616     drck->isolate = drc_isolate_physical;
617     drck->unisolate = drc_unisolate_physical;
618 }
619 
620 static void spapr_drc_logical_class_init(ObjectClass *k, void *data)
621 {
622     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
623 
624     drck->dr_entity_sense = logical_entity_sense;
625     drck->isolate = drc_isolate_logical;
626     drck->unisolate = drc_unisolate_logical;
627 }
628 
629 static void spapr_drc_cpu_class_init(ObjectClass *k, void *data)
630 {
631     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
632 
633     drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU;
634     drck->typename = "CPU";
635     drck->drc_name_prefix = "CPU ";
636 }
637 
638 static void spapr_drc_pci_class_init(ObjectClass *k, void *data)
639 {
640     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
641 
642     drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI;
643     drck->typename = "28";
644     drck->drc_name_prefix = "C";
645 }
646 
647 static void spapr_drc_lmb_class_init(ObjectClass *k, void *data)
648 {
649     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
650 
651     drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB;
652     drck->typename = "MEM";
653     drck->drc_name_prefix = "LMB ";
654 }
655 
656 static const TypeInfo spapr_dr_connector_info = {
657     .name          = TYPE_SPAPR_DR_CONNECTOR,
658     .parent        = TYPE_DEVICE,
659     .instance_size = sizeof(sPAPRDRConnector),
660     .instance_init = spapr_dr_connector_instance_init,
661     .class_size    = sizeof(sPAPRDRConnectorClass),
662     .class_init    = spapr_dr_connector_class_init,
663     .abstract      = true,
664 };
665 
666 static const TypeInfo spapr_drc_physical_info = {
667     .name          = TYPE_SPAPR_DRC_PHYSICAL,
668     .parent        = TYPE_SPAPR_DR_CONNECTOR,
669     .instance_size = sizeof(sPAPRDRConnector),
670     .class_init    = spapr_drc_physical_class_init,
671     .abstract      = true,
672 };
673 
674 static const TypeInfo spapr_drc_logical_info = {
675     .name          = TYPE_SPAPR_DRC_LOGICAL,
676     .parent        = TYPE_SPAPR_DR_CONNECTOR,
677     .instance_size = sizeof(sPAPRDRConnector),
678     .class_init    = spapr_drc_logical_class_init,
679     .abstract      = true,
680 };
681 
682 static const TypeInfo spapr_drc_cpu_info = {
683     .name          = TYPE_SPAPR_DRC_CPU,
684     .parent        = TYPE_SPAPR_DRC_LOGICAL,
685     .instance_size = sizeof(sPAPRDRConnector),
686     .class_init    = spapr_drc_cpu_class_init,
687 };
688 
689 static const TypeInfo spapr_drc_pci_info = {
690     .name          = TYPE_SPAPR_DRC_PCI,
691     .parent        = TYPE_SPAPR_DRC_PHYSICAL,
692     .instance_size = sizeof(sPAPRDRConnector),
693     .class_init    = spapr_drc_pci_class_init,
694 };
695 
696 static const TypeInfo spapr_drc_lmb_info = {
697     .name          = TYPE_SPAPR_DRC_LMB,
698     .parent        = TYPE_SPAPR_DRC_LOGICAL,
699     .instance_size = sizeof(sPAPRDRConnector),
700     .class_init    = spapr_drc_lmb_class_init,
701 };
702 
703 /* helper functions for external users */
704 
705 sPAPRDRConnector *spapr_drc_by_index(uint32_t index)
706 {
707     Object *obj;
708     char name[256];
709 
710     snprintf(name, sizeof(name), "%s/%x", DRC_CONTAINER_PATH, index);
711     obj = object_resolve_path(name, NULL);
712 
713     return !obj ? NULL : SPAPR_DR_CONNECTOR(obj);
714 }
715 
716 sPAPRDRConnector *spapr_drc_by_id(const char *type, uint32_t id)
717 {
718     sPAPRDRConnectorClass *drck
719         = SPAPR_DR_CONNECTOR_CLASS(object_class_by_name(type));
720 
721     return spapr_drc_by_index(drck->typeshift << DRC_INDEX_TYPE_SHIFT
722                               | (id & DRC_INDEX_ID_MASK));
723 }
724 
725 /**
726  * spapr_drc_populate_dt
727  *
728  * @fdt: libfdt device tree
729  * @path: path in the DT to generate properties
730  * @owner: parent Object/DeviceState for which to generate DRC
731  *         descriptions for
732  * @drc_type_mask: mask of sPAPRDRConnectorType values corresponding
733  *   to the types of DRCs to generate entries for
734  *
735  * generate OF properties to describe DRC topology/indices to guests
736  *
737  * as documented in PAPR+ v2.1, 13.5.2
738  */
739 int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
740                           uint32_t drc_type_mask)
741 {
742     Object *root_container;
743     ObjectProperty *prop;
744     ObjectPropertyIterator iter;
745     uint32_t drc_count = 0;
746     GArray *drc_indexes, *drc_power_domains;
747     GString *drc_names, *drc_types;
748     int ret;
749 
750     /* the first entry of each properties is a 32-bit integer encoding
751      * the number of elements in the array. we won't know this until
752      * we complete the iteration through all the matching DRCs, but
753      * reserve the space now and set the offsets accordingly so we
754      * can fill them in later.
755      */
756     drc_indexes = g_array_new(false, true, sizeof(uint32_t));
757     drc_indexes = g_array_set_size(drc_indexes, 1);
758     drc_power_domains = g_array_new(false, true, sizeof(uint32_t));
759     drc_power_domains = g_array_set_size(drc_power_domains, 1);
760     drc_names = g_string_set_size(g_string_new(NULL), sizeof(uint32_t));
761     drc_types = g_string_set_size(g_string_new(NULL), sizeof(uint32_t));
762 
763     /* aliases for all DRConnector objects will be rooted in QOM
764      * composition tree at DRC_CONTAINER_PATH
765      */
766     root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
767 
768     object_property_iter_init(&iter, root_container);
769     while ((prop = object_property_iter_next(&iter))) {
770         Object *obj;
771         sPAPRDRConnector *drc;
772         sPAPRDRConnectorClass *drck;
773         uint32_t drc_index, drc_power_domain;
774 
775         if (!strstart(prop->type, "link<", NULL)) {
776             continue;
777         }
778 
779         obj = object_property_get_link(root_container, prop->name, NULL);
780         drc = SPAPR_DR_CONNECTOR(obj);
781         drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
782 
783         if (owner && (drc->owner != owner)) {
784             continue;
785         }
786 
787         if ((spapr_drc_type(drc) & drc_type_mask) == 0) {
788             continue;
789         }
790 
791         drc_count++;
792 
793         /* ibm,drc-indexes */
794         drc_index = cpu_to_be32(spapr_drc_index(drc));
795         g_array_append_val(drc_indexes, drc_index);
796 
797         /* ibm,drc-power-domains */
798         drc_power_domain = cpu_to_be32(-1);
799         g_array_append_val(drc_power_domains, drc_power_domain);
800 
801         /* ibm,drc-names */
802         drc_names = g_string_append(drc_names, spapr_drc_name(drc));
803         drc_names = g_string_insert_len(drc_names, -1, "\0", 1);
804 
805         /* ibm,drc-types */
806         drc_types = g_string_append(drc_types, drck->typename);
807         drc_types = g_string_insert_len(drc_types, -1, "\0", 1);
808     }
809 
810     /* now write the drc count into the space we reserved at the
811      * beginning of the arrays previously
812      */
813     *(uint32_t *)drc_indexes->data = cpu_to_be32(drc_count);
814     *(uint32_t *)drc_power_domains->data = cpu_to_be32(drc_count);
815     *(uint32_t *)drc_names->str = cpu_to_be32(drc_count);
816     *(uint32_t *)drc_types->str = cpu_to_be32(drc_count);
817 
818     ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-indexes",
819                       drc_indexes->data,
820                       drc_indexes->len * sizeof(uint32_t));
821     if (ret) {
822         error_report("Couldn't create ibm,drc-indexes property");
823         goto out;
824     }
825 
826     ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-power-domains",
827                       drc_power_domains->data,
828                       drc_power_domains->len * sizeof(uint32_t));
829     if (ret) {
830         error_report("Couldn't finalize ibm,drc-power-domains property");
831         goto out;
832     }
833 
834     ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-names",
835                       drc_names->str, drc_names->len);
836     if (ret) {
837         error_report("Couldn't finalize ibm,drc-names property");
838         goto out;
839     }
840 
841     ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-types",
842                       drc_types->str, drc_types->len);
843     if (ret) {
844         error_report("Couldn't finalize ibm,drc-types property");
845         goto out;
846     }
847 
848 out:
849     g_array_free(drc_indexes, true);
850     g_array_free(drc_power_domains, true);
851     g_string_free(drc_names, true);
852     g_string_free(drc_types, true);
853 
854     return ret;
855 }
856 
857 /*
858  * RTAS calls
859  */
860 
861 static uint32_t rtas_set_isolation_state(uint32_t idx, uint32_t state)
862 {
863     sPAPRDRConnector *drc = spapr_drc_by_index(idx);
864     sPAPRDRConnectorClass *drck;
865 
866     if (!drc) {
867         return RTAS_OUT_NO_SUCH_INDICATOR;
868     }
869 
870     trace_spapr_drc_set_isolation_state(spapr_drc_index(drc), state);
871 
872     drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
873 
874     switch (state) {
875     case SPAPR_DR_ISOLATION_STATE_ISOLATED:
876         return drck->isolate(drc);
877 
878     case SPAPR_DR_ISOLATION_STATE_UNISOLATED:
879         return drck->unisolate(drc);
880 
881     default:
882         return RTAS_OUT_PARAM_ERROR;
883     }
884 }
885 
886 static uint32_t rtas_set_allocation_state(uint32_t idx, uint32_t state)
887 {
888     sPAPRDRConnector *drc = spapr_drc_by_index(idx);
889 
890     if (!drc || !object_dynamic_cast(OBJECT(drc), TYPE_SPAPR_DRC_LOGICAL)) {
891         return RTAS_OUT_NO_SUCH_INDICATOR;
892     }
893 
894     trace_spapr_drc_set_allocation_state(spapr_drc_index(drc), state);
895 
896     switch (state) {
897     case SPAPR_DR_ALLOCATION_STATE_USABLE:
898         return drc_set_usable(drc);
899 
900     case SPAPR_DR_ALLOCATION_STATE_UNUSABLE:
901         return drc_set_unusable(drc);
902 
903     default:
904         return RTAS_OUT_PARAM_ERROR;
905     }
906 }
907 
908 static uint32_t rtas_set_dr_indicator(uint32_t idx, uint32_t state)
909 {
910     sPAPRDRConnector *drc = spapr_drc_by_index(idx);
911 
912     if (!drc) {
913         return RTAS_OUT_PARAM_ERROR;
914     }
915 
916     trace_spapr_drc_set_dr_indicator(idx, state);
917     drc->dr_indicator = state;
918     return RTAS_OUT_SUCCESS;
919 }
920 
921 static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr,
922                                uint32_t token,
923                                uint32_t nargs, target_ulong args,
924                                uint32_t nret, target_ulong rets)
925 {
926     uint32_t type, idx, state;
927     uint32_t ret = RTAS_OUT_SUCCESS;
928 
929     if (nargs != 3 || nret != 1) {
930         ret = RTAS_OUT_PARAM_ERROR;
931         goto out;
932     }
933 
934     type = rtas_ld(args, 0);
935     idx = rtas_ld(args, 1);
936     state = rtas_ld(args, 2);
937 
938     switch (type) {
939     case RTAS_SENSOR_TYPE_ISOLATION_STATE:
940         ret = rtas_set_isolation_state(idx, state);
941         break;
942     case RTAS_SENSOR_TYPE_DR:
943         ret = rtas_set_dr_indicator(idx, state);
944         break;
945     case RTAS_SENSOR_TYPE_ALLOCATION_STATE:
946         ret = rtas_set_allocation_state(idx, state);
947         break;
948     default:
949         ret = RTAS_OUT_NOT_SUPPORTED;
950     }
951 
952 out:
953     rtas_st(rets, 0, ret);
954 }
955 
956 static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr,
957                                   uint32_t token, uint32_t nargs,
958                                   target_ulong args, uint32_t nret,
959                                   target_ulong rets)
960 {
961     uint32_t sensor_type;
962     uint32_t sensor_index;
963     uint32_t sensor_state = 0;
964     sPAPRDRConnector *drc;
965     sPAPRDRConnectorClass *drck;
966     uint32_t ret = RTAS_OUT_SUCCESS;
967 
968     if (nargs != 2 || nret != 2) {
969         ret = RTAS_OUT_PARAM_ERROR;
970         goto out;
971     }
972 
973     sensor_type = rtas_ld(args, 0);
974     sensor_index = rtas_ld(args, 1);
975 
976     if (sensor_type != RTAS_SENSOR_TYPE_ENTITY_SENSE) {
977         /* currently only DR-related sensors are implemented */
978         trace_spapr_rtas_get_sensor_state_not_supported(sensor_index,
979                                                         sensor_type);
980         ret = RTAS_OUT_NOT_SUPPORTED;
981         goto out;
982     }
983 
984     drc = spapr_drc_by_index(sensor_index);
985     if (!drc) {
986         trace_spapr_rtas_get_sensor_state_invalid(sensor_index);
987         ret = RTAS_OUT_PARAM_ERROR;
988         goto out;
989     }
990     drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
991     sensor_state = drck->dr_entity_sense(drc);
992 
993 out:
994     rtas_st(rets, 0, ret);
995     rtas_st(rets, 1, sensor_state);
996 }
997 
998 /* configure-connector work area offsets, int32_t units for field
999  * indexes, bytes for field offset/len values.
1000  *
1001  * as documented by PAPR+ v2.7, 13.5.3.5
1002  */
1003 #define CC_IDX_NODE_NAME_OFFSET 2
1004 #define CC_IDX_PROP_NAME_OFFSET 2
1005 #define CC_IDX_PROP_LEN 3
1006 #define CC_IDX_PROP_DATA_OFFSET 4
1007 #define CC_VAL_DATA_OFFSET ((CC_IDX_PROP_DATA_OFFSET + 1) * 4)
1008 #define CC_WA_LEN 4096
1009 
1010 static void configure_connector_st(target_ulong addr, target_ulong offset,
1011                                    const void *buf, size_t len)
1012 {
1013     cpu_physical_memory_write(ppc64_phys_to_real(addr + offset),
1014                               buf, MIN(len, CC_WA_LEN - offset));
1015 }
1016 
1017 static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
1018                                          sPAPRMachineState *spapr,
1019                                          uint32_t token, uint32_t nargs,
1020                                          target_ulong args, uint32_t nret,
1021                                          target_ulong rets)
1022 {
1023     uint64_t wa_addr;
1024     uint64_t wa_offset;
1025     uint32_t drc_index;
1026     sPAPRDRConnector *drc;
1027     sPAPRConfigureConnectorState *ccs;
1028     sPAPRDRCCResponse resp = SPAPR_DR_CC_RESPONSE_CONTINUE;
1029     int rc;
1030 
1031     if (nargs != 2 || nret != 1) {
1032         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
1033         return;
1034     }
1035 
1036     wa_addr = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 0);
1037 
1038     drc_index = rtas_ld(wa_addr, 0);
1039     drc = spapr_drc_by_index(drc_index);
1040     if (!drc) {
1041         trace_spapr_rtas_ibm_configure_connector_invalid(drc_index);
1042         rc = RTAS_OUT_PARAM_ERROR;
1043         goto out;
1044     }
1045 
1046     if (!drc->fdt) {
1047         trace_spapr_rtas_ibm_configure_connector_missing_fdt(drc_index);
1048         rc = SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE;
1049         goto out;
1050     }
1051 
1052     ccs = drc->ccs;
1053     if (!ccs) {
1054         ccs = g_new0(sPAPRConfigureConnectorState, 1);
1055         ccs->fdt_offset = drc->fdt_start_offset;
1056         drc->ccs = ccs;
1057     }
1058 
1059     do {
1060         uint32_t tag;
1061         const char *name;
1062         const struct fdt_property *prop;
1063         int fdt_offset_next, prop_len;
1064 
1065         tag = fdt_next_tag(drc->fdt, ccs->fdt_offset, &fdt_offset_next);
1066 
1067         switch (tag) {
1068         case FDT_BEGIN_NODE:
1069             ccs->fdt_depth++;
1070             name = fdt_get_name(drc->fdt, ccs->fdt_offset, NULL);
1071 
1072             /* provide the name of the next OF node */
1073             wa_offset = CC_VAL_DATA_OFFSET;
1074             rtas_st(wa_addr, CC_IDX_NODE_NAME_OFFSET, wa_offset);
1075             configure_connector_st(wa_addr, wa_offset, name, strlen(name) + 1);
1076             resp = SPAPR_DR_CC_RESPONSE_NEXT_CHILD;
1077             break;
1078         case FDT_END_NODE:
1079             ccs->fdt_depth--;
1080             if (ccs->fdt_depth == 0) {
1081                 sPAPRDRIsolationState state = drc->isolation_state;
1082                 uint32_t drc_index = spapr_drc_index(drc);
1083                 /* done sending the device tree, don't need to track
1084                  * the state anymore
1085                  */
1086                 trace_spapr_drc_set_configured(drc_index);
1087                 if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
1088                     drc->configured = true;
1089                 } else {
1090                     /* guest should be not configuring an isolated device */
1091                     trace_spapr_drc_set_configured_skipping(drc_index);
1092                 }
1093                 g_free(ccs);
1094                 drc->ccs = NULL;
1095                 ccs = NULL;
1096                 resp = SPAPR_DR_CC_RESPONSE_SUCCESS;
1097             } else {
1098                 resp = SPAPR_DR_CC_RESPONSE_PREV_PARENT;
1099             }
1100             break;
1101         case FDT_PROP:
1102             prop = fdt_get_property_by_offset(drc->fdt, ccs->fdt_offset,
1103                                               &prop_len);
1104             name = fdt_string(drc->fdt, fdt32_to_cpu(prop->nameoff));
1105 
1106             /* provide the name of the next OF property */
1107             wa_offset = CC_VAL_DATA_OFFSET;
1108             rtas_st(wa_addr, CC_IDX_PROP_NAME_OFFSET, wa_offset);
1109             configure_connector_st(wa_addr, wa_offset, name, strlen(name) + 1);
1110 
1111             /* provide the length and value of the OF property. data gets
1112              * placed immediately after NULL terminator of the OF property's
1113              * name string
1114              */
1115             wa_offset += strlen(name) + 1,
1116             rtas_st(wa_addr, CC_IDX_PROP_LEN, prop_len);
1117             rtas_st(wa_addr, CC_IDX_PROP_DATA_OFFSET, wa_offset);
1118             configure_connector_st(wa_addr, wa_offset, prop->data, prop_len);
1119             resp = SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY;
1120             break;
1121         case FDT_END:
1122             resp = SPAPR_DR_CC_RESPONSE_ERROR;
1123         default:
1124             /* keep seeking for an actionable tag */
1125             break;
1126         }
1127         if (ccs) {
1128             ccs->fdt_offset = fdt_offset_next;
1129         }
1130     } while (resp == SPAPR_DR_CC_RESPONSE_CONTINUE);
1131 
1132     rc = resp;
1133 out:
1134     rtas_st(rets, 0, rc);
1135 }
1136 
1137 static void spapr_drc_register_types(void)
1138 {
1139     type_register_static(&spapr_dr_connector_info);
1140     type_register_static(&spapr_drc_physical_info);
1141     type_register_static(&spapr_drc_logical_info);
1142     type_register_static(&spapr_drc_cpu_info);
1143     type_register_static(&spapr_drc_pci_info);
1144     type_register_static(&spapr_drc_lmb_info);
1145 
1146     spapr_rtas_register(RTAS_SET_INDICATOR, "set-indicator",
1147                         rtas_set_indicator);
1148     spapr_rtas_register(RTAS_GET_SENSOR_STATE, "get-sensor-state",
1149                         rtas_get_sensor_state);
1150     spapr_rtas_register(RTAS_IBM_CONFIGURE_CONNECTOR, "ibm,configure-connector",
1151                         rtas_ibm_configure_connector);
1152 }
1153 type_init(spapr_drc_register_types)
1154