]> git.proxmox.com Git - mirror_qemu.git/blame - hw/ppc/spapr_drc.c
Drop duplicate #include
[mirror_qemu.git] / hw / ppc / spapr_drc.c
CommitLineData
bbf5c878
MR
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
0d75590d 13#include "qemu/osdep.h"
da34e65c 14#include "qapi/error.h"
15280c36 15#include "qapi/qmp/qnull.h"
f348b6d1 16#include "qemu/cutils.h"
bbf5c878
MR
17#include "hw/ppc/spapr_drc.h"
18#include "qom/object.h"
d6454270 19#include "migration/vmstate.h"
4b08cd56 20#include "qapi/qapi-events-qdev.h"
bbf5c878
MR
21#include "qapi/visitor.h"
22#include "qemu/error-report.h"
0cb688d2 23#include "hw/ppc/spapr.h" /* for RTAS return codes */
31834723 24#include "hw/pci-host/spapr.h" /* spapr_phb_remove_pci_device_cb callback */
ee3a71e3 25#include "hw/ppc/spapr_nvdimm.h"
d9c95c71 26#include "sysemu/device_tree.h"
71e8a915 27#include "sysemu/reset.h"
24ac7755 28#include "trace.h"
bbf5c878
MR
29
30#define DRC_CONTAINER_PATH "/dr-connector"
31#define DRC_INDEX_TYPE_SHIFT 28
627c2ef7 32#define DRC_INDEX_ID_MASK ((1ULL << DRC_INDEX_TYPE_SHIFT) - 1)
bbf5c878 33
ce2918cb 34SpaprDrcType spapr_drc_type(SpaprDrc *drc)
2d335818 35{
ce2918cb 36 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
2d335818
DG
37
38 return 1 << drck->typeshift;
39}
40
ce2918cb 41uint32_t spapr_drc_index(SpaprDrc *drc)
bbf5c878 42{
ce2918cb 43 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
2d335818 44
bbf5c878
MR
45 /* no set format for a drc index: it only needs to be globally
46 * unique. this is how we encode the DRC type on bare-metal
47 * however, so might as well do that here
48 */
2d335818
DG
49 return (drck->typeshift << DRC_INDEX_TYPE_SHIFT)
50 | (drc->id & DRC_INDEX_ID_MASK);
bbf5c878
MR
51}
52
66d10d32
DHB
53static void spapr_drc_release(SpaprDrc *drc)
54{
55 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
56
57 drck->release(drc->dev);
58
59 drc->unplug_requested = false;
60 g_free(drc->fdt);
61 drc->fdt = NULL;
62 drc->fdt_start_offset = 0;
63 object_property_del(OBJECT(drc), "device");
64 drc->dev = NULL;
65}
66
ce2918cb 67static uint32_t drc_isolate_physical(SpaprDrc *drc)
bbf5c878 68{
9d4c0f4f
DG
69 switch (drc->state) {
70 case SPAPR_DRC_STATE_PHYSICAL_POWERON:
71 return RTAS_OUT_SUCCESS; /* Nothing to do */
72 case SPAPR_DRC_STATE_PHYSICAL_CONFIGURED:
73 break; /* see below */
74 case SPAPR_DRC_STATE_PHYSICAL_UNISOLATE:
75 return RTAS_OUT_PARAM_ERROR; /* not allowed */
76 default:
77 g_assert_not_reached();
78 }
79
9d4c0f4f 80 drc->state = SPAPR_DRC_STATE_PHYSICAL_POWERON;
0dfabd39 81
f1c52354 82 if (drc->unplug_requested) {
0dfabd39 83 uint32_t drc_index = spapr_drc_index(drc);
9d4c0f4f 84 trace_spapr_drc_set_isolation_state_finalizing(drc_index);
66d10d32 85 spapr_drc_release(drc);
9d1852ce 86 }
0dfabd39
DG
87
88 return RTAS_OUT_SUCCESS;
89}
90
ce2918cb 91static uint32_t drc_unisolate_physical(SpaprDrc *drc)
0dfabd39 92{
9d4c0f4f
DG
93 switch (drc->state) {
94 case SPAPR_DRC_STATE_PHYSICAL_UNISOLATE:
95 case SPAPR_DRC_STATE_PHYSICAL_CONFIGURED:
96 return RTAS_OUT_SUCCESS; /* Nothing to do */
97 case SPAPR_DRC_STATE_PHYSICAL_POWERON:
98 break; /* see below */
99 default:
100 g_assert_not_reached();
101 }
102
0dfabd39
DG
103 /* cannot unisolate a non-existent resource, and, or resources
104 * which are in an 'UNUSABLE' allocation state. (PAPR 2.7,
105 * 13.5.3.5)
106 */
107 if (!drc->dev) {
108 return RTAS_OUT_NO_SUCH_INDICATOR;
109 }
110
9d4c0f4f 111 drc->state = SPAPR_DRC_STATE_PHYSICAL_UNISOLATE;
4445b1d2
DG
112 drc->ccs_offset = drc->fdt_start_offset;
113 drc->ccs_depth = 0;
0dfabd39
DG
114
115 return RTAS_OUT_SUCCESS;
116}
117
ce2918cb 118static uint32_t drc_isolate_logical(SpaprDrc *drc)
0dfabd39 119{
9d4c0f4f
DG
120 switch (drc->state) {
121 case SPAPR_DRC_STATE_LOGICAL_AVAILABLE:
122 case SPAPR_DRC_STATE_LOGICAL_UNUSABLE:
123 return RTAS_OUT_SUCCESS; /* Nothing to do */
124 case SPAPR_DRC_STATE_LOGICAL_CONFIGURED:
125 break; /* see below */
126 case SPAPR_DRC_STATE_LOGICAL_UNISOLATE:
127 return RTAS_OUT_PARAM_ERROR; /* not allowed */
128 default:
129 g_assert_not_reached();
130 }
131
cf632463
BR
132 /*
133 * Fail any requests to ISOLATE the LMB DRC if this LMB doesn't
134 * belong to a DIMM device that is marked for removal.
135 *
136 * Currently the guest userspace tool drmgr that drives the memory
137 * hotplug/unplug will just try to remove a set of 'removable' LMBs
138 * in response to a hot unplug request that is based on drc-count.
139 * If the LMB being removed doesn't belong to a DIMM device that is
140 * actually being unplugged, fail the isolation request here.
141 */
0dfabd39 142 if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB
f1c52354 143 && !drc->unplug_requested) {
0dfabd39 144 return RTAS_OUT_HW_ERROR;
cf632463
BR
145 }
146
9d4c0f4f 147 drc->state = SPAPR_DRC_STATE_LOGICAL_AVAILABLE;
bbf5c878 148
0dfabd39
DG
149 return RTAS_OUT_SUCCESS;
150}
151
ce2918cb 152static uint32_t drc_unisolate_logical(SpaprDrc *drc)
0dfabd39 153{
87758fed
DHB
154 SpaprMachineState *spapr = NULL;
155
9d4c0f4f
DG
156 switch (drc->state) {
157 case SPAPR_DRC_STATE_LOGICAL_UNISOLATE:
158 case SPAPR_DRC_STATE_LOGICAL_CONFIGURED:
87758fed
DHB
159 /*
160 * Unisolating a logical DRC that was marked for unplug
161 * means that the kernel is refusing the removal.
162 */
163 if (drc->unplug_requested && drc->dev) {
164 if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB) {
165 spapr = SPAPR_MACHINE(qdev_get_machine());
166
167 spapr_memory_unplug_rollback(spapr, drc->dev);
168 }
169
170 drc->unplug_requested = false;
91bd95ce
DHB
171
172 if (drc->dev->id) {
173 error_report("Device hotunplug rejected by the guest "
174 "for device %s", drc->dev->id);
175 }
87758fed 176
047f2ca1 177 qapi_event_send_device_unplug_guest_error(drc->dev->id,
4b08cd56 178 drc->dev->canonical_path);
87758fed
DHB
179 }
180
9d4c0f4f
DG
181 return RTAS_OUT_SUCCESS; /* Nothing to do */
182 case SPAPR_DRC_STATE_LOGICAL_AVAILABLE:
183 break; /* see below */
184 case SPAPR_DRC_STATE_LOGICAL_UNUSABLE:
185 return RTAS_OUT_NO_SUCH_INDICATOR; /* not allowed */
186 default:
187 g_assert_not_reached();
0dfabd39
DG
188 }
189
9d4c0f4f
DG
190 /* Move to AVAILABLE state should have ensured device was present */
191 g_assert(drc->dev);
bbf5c878 192
9d4c0f4f 193 drc->state = SPAPR_DRC_STATE_LOGICAL_UNISOLATE;
4445b1d2
DG
194 drc->ccs_offset = drc->fdt_start_offset;
195 drc->ccs_depth = 0;
196
0cb688d2 197 return RTAS_OUT_SUCCESS;
bbf5c878
MR
198}
199
ce2918cb 200static uint32_t drc_set_usable(SpaprDrc *drc)
bbf5c878 201{
9d4c0f4f
DG
202 switch (drc->state) {
203 case SPAPR_DRC_STATE_LOGICAL_AVAILABLE:
204 case SPAPR_DRC_STATE_LOGICAL_UNISOLATE:
205 case SPAPR_DRC_STATE_LOGICAL_CONFIGURED:
206 return RTAS_OUT_SUCCESS; /* Nothing to do */
207 case SPAPR_DRC_STATE_LOGICAL_UNUSABLE:
208 break; /* see below */
209 default:
210 g_assert_not_reached();
211 }
212
61736732
DG
213 /* if there's no resource/device associated with the DRC, there's
214 * no way for us to put it in an allocation state consistent with
215 * being 'USABLE'. PAPR 2.7, 13.5.3.4 documents that this should
216 * result in an RTAS return code of -3 / "no such indicator"
217 */
218 if (!drc->dev) {
219 return RTAS_OUT_NO_SUCH_INDICATOR;
220 }
f1c52354 221 if (drc->unplug_requested) {
82a93a1d
DG
222 /* Don't allow the guest to move a device away from UNUSABLE
223 * state when we want to unplug it */
61736732 224 return RTAS_OUT_NO_SUCH_INDICATOR;
9d1852ce
MR
225 }
226
9d4c0f4f 227 drc->state = SPAPR_DRC_STATE_LOGICAL_AVAILABLE;
61736732
DG
228
229 return RTAS_OUT_SUCCESS;
230}
231
ce2918cb 232static uint32_t drc_set_unusable(SpaprDrc *drc)
61736732 233{
9d4c0f4f
DG
234 switch (drc->state) {
235 case SPAPR_DRC_STATE_LOGICAL_UNUSABLE:
236 return RTAS_OUT_SUCCESS; /* Nothing to do */
237 case SPAPR_DRC_STATE_LOGICAL_AVAILABLE:
238 break; /* see below */
239 case SPAPR_DRC_STATE_LOGICAL_UNISOLATE:
240 case SPAPR_DRC_STATE_LOGICAL_CONFIGURED:
241 return RTAS_OUT_NO_SUCH_INDICATOR; /* not allowed */
242 default:
243 g_assert_not_reached();
244 }
245
246 drc->state = SPAPR_DRC_STATE_LOGICAL_UNUSABLE;
f1c52354 247 if (drc->unplug_requested) {
61736732
DG
248 uint32_t drc_index = spapr_drc_index(drc);
249 trace_spapr_drc_set_allocation_state_finalizing(drc_index);
66d10d32 250 spapr_drc_release(drc);
bbf5c878 251 }
61736732 252
0cb688d2 253 return RTAS_OUT_SUCCESS;
bbf5c878
MR
254}
255
dbd26f2f 256static char *spapr_drc_name(SpaprDrc *drc)
bbf5c878 257{
ce2918cb 258 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
79808336
DG
259
260 /* human-readable name for a DRC to encode into the DT
261 * description. this is mainly only used within a guest in place
262 * of the unique DRC index.
263 *
264 * in the case of VIO/PCI devices, it corresponds to a "location
265 * code" that maps a logical device/function (DRC index) to a
266 * physical (or virtual in the case of VIO) location in the system
267 * by chaining together the "location label" for each
268 * encapsulating component.
269 *
270 * since this is more to do with diagnosing physical hardware
271 * issues than guest compatibility, we choose location codes/DRC
272 * names that adhere to the documented format, but avoid encoding
273 * the entire topology information into the label/code, instead
274 * just using the location codes based on the labels for the
275 * endpoints (VIO/PCI adaptor connectors), which is basically just
276 * "C" followed by an integer ID.
277 *
278 * DRC names as documented by PAPR+ v2.7, 13.5.2.4
279 * location codes as documented by PAPR+ v2.7, 12.3.1.5
280 */
281 return g_strdup_printf("%s%d", drck->drc_name_prefix, drc->id);
bbf5c878
MR
282}
283
bbf5c878
MR
284/*
285 * dr-entity-sense sensor value
286 * returned via get-sensor-state RTAS calls
287 * as expected by state diagram in PAPR+ 2.7, 13.4
288 * based on the current allocation/indicator/power states
289 * for the DR connector.
290 */
ce2918cb 291static SpaprDREntitySense physical_entity_sense(SpaprDrc *drc)
bbf5c878 292{
f224d35b
DG
293 /* this assumes all PCI devices are assigned to a 'live insertion'
294 * power domain, where QEMU manages power state automatically as
295 * opposed to the guest. present, non-PCI resources are unaffected
296 * by power state.
297 */
298 return drc->dev ? SPAPR_DR_ENTITY_SENSE_PRESENT
299 : SPAPR_DR_ENTITY_SENSE_EMPTY;
300}
301
ce2918cb 302static SpaprDREntitySense logical_entity_sense(SpaprDrc *drc)
f224d35b 303{
9d4c0f4f
DG
304 switch (drc->state) {
305 case SPAPR_DRC_STATE_LOGICAL_UNUSABLE:
f224d35b 306 return SPAPR_DR_ENTITY_SENSE_UNUSABLE;
9d4c0f4f
DG
307 case SPAPR_DRC_STATE_LOGICAL_AVAILABLE:
308 case SPAPR_DRC_STATE_LOGICAL_UNISOLATE:
309 case SPAPR_DRC_STATE_LOGICAL_CONFIGURED:
310 g_assert(drc->dev);
311 return SPAPR_DR_ENTITY_SENSE_PRESENT;
312 default:
313 g_assert_not_reached();
bbf5c878 314 }
bbf5c878
MR
315}
316
d7bce999
EB
317static void prop_get_index(Object *obj, Visitor *v, const char *name,
318 void *opaque, Error **errp)
bbf5c878 319{
ce2918cb 320 SpaprDrc *drc = SPAPR_DR_CONNECTOR(obj);
0b55aa91 321 uint32_t value = spapr_drc_index(drc);
51e72bc1 322 visit_type_uint32(v, name, &value, errp);
bbf5c878
MR
323}
324
d7bce999
EB
325static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
326 void *opaque, Error **errp)
bbf5c878 327{
ce2918cb 328 SpaprDrc *drc = SPAPR_DR_CONNECTOR(obj);
d2f95f4d 329 QNull *null = NULL;
bbf5c878
MR
330 int fdt_offset_next, fdt_offset, fdt_depth;
331 void *fdt;
332
333 if (!drc->fdt) {
d2f95f4d 334 visit_type_null(v, NULL, &null, errp);
cb3e7f08 335 qobject_unref(null);
bbf5c878
MR
336 return;
337 }
338
339 fdt = drc->fdt;
340 fdt_offset = drc->fdt_start_offset;
341 fdt_depth = 0;
342
343 do {
344 const char *name = NULL;
345 const struct fdt_property *prop = NULL;
346 int prop_len = 0, name_len = 0;
347 uint32_t tag;
ebd226d2 348 bool ok;
bbf5c878
MR
349
350 tag = fdt_next_tag(fdt, fdt_offset, &fdt_offset_next);
351 switch (tag) {
352 case FDT_BEGIN_NODE:
353 fdt_depth++;
354 name = fdt_get_name(fdt, fdt_offset, &name_len);
668f62ec 355 if (!visit_start_struct(v, name, NULL, 0, errp)) {
c75304a1
MA
356 return;
357 }
bbf5c878
MR
358 break;
359 case FDT_END_NODE:
360 /* shouldn't ever see an FDT_END_NODE before FDT_BEGIN_NODE */
361 g_assert(fdt_depth > 0);
ebd226d2 362 ok = visit_check_struct(v, errp);
1158bb2a 363 visit_end_struct(v, NULL);
ebd226d2 364 if (!ok) {
c75304a1
MA
365 return;
366 }
bbf5c878
MR
367 fdt_depth--;
368 break;
369 case FDT_PROP: {
370 int i;
371 prop = fdt_get_property_by_offset(fdt, fdt_offset, &prop_len);
372 name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
668f62ec 373 if (!visit_start_list(v, name, NULL, 0, errp)) {
c75304a1
MA
374 return;
375 }
bbf5c878 376 for (i = 0; i < prop_len; i++) {
62a35aaa 377 if (!visit_type_uint8(v, NULL, (uint8_t *)&prop->data[i],
668f62ec 378 errp)) {
c75304a1
MA
379 return;
380 }
381 }
ebd226d2 382 ok = visit_check_list(v, errp);
1158bb2a 383 visit_end_list(v, NULL);
ebd226d2 384 if (!ok) {
a4a1c70d
MA
385 return;
386 }
bbf5c878
MR
387 break;
388 }
389 default:
e20c6314
PMD
390 error_report("device FDT in unexpected state: %d", tag);
391 abort();
bbf5c878
MR
392 }
393 fdt_offset = fdt_offset_next;
394 } while (fdt_depth != 0);
395}
396
bc370a65 397void spapr_drc_attach(SpaprDrc *drc, DeviceState *d)
bbf5c878 398{
0b55aa91 399 trace_spapr_drc_attach(spapr_drc_index(drc));
bbf5c878 400
bc370a65 401 g_assert(!drc->dev);
9d4c0f4f
DG
402 g_assert((drc->state == SPAPR_DRC_STATE_LOGICAL_UNUSABLE)
403 || (drc->state == SPAPR_DRC_STATE_PHYSICAL_POWERON));
bbf5c878 404
bbf5c878 405 drc->dev = d;
d9c95c71 406
bbf5c878
MR
407 object_property_add_link(OBJECT(drc), "device",
408 object_get_typename(OBJECT(drc->dev)),
409 (Object **)(&drc->dev),
d2623129 410 NULL, 0);
bbf5c878
MR
411}
412
a03509cd 413void spapr_drc_unplug_request(SpaprDrc *drc)
9c914e53 414{
ce2918cb 415 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
9d4c0f4f 416
a03509cd 417 trace_spapr_drc_unplug_request(spapr_drc_index(drc));
9c914e53 418
9d4c0f4f 419 g_assert(drc->dev);
a8dc47fd 420
9d4c0f4f 421 drc->unplug_requested = true;
9c914e53 422
9d4c0f4f
DG
423 if (drc->state != drck->empty_state) {
424 trace_spapr_drc_awaiting_quiesce(spapr_drc_index(drc));
9c914e53
DG
425 return;
426 }
427
9c914e53
DG
428 spapr_drc_release(drc);
429}
430
930ef3b5 431bool spapr_drc_reset(SpaprDrc *drc)
bbf5c878 432{
ce2918cb 433 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
930ef3b5 434 bool unplug_completed = false;
9d4c0f4f 435
0b55aa91 436 trace_spapr_drc_reset(spapr_drc_index(drc));
b8fdd530 437
bbf5c878 438 /* immediately upon reset we can safely assume DRCs whose devices
4f9242fc 439 * are pending removal can be safely removed.
bbf5c878 440 */
f1c52354 441 if (drc->unplug_requested) {
4f9242fc 442 spapr_drc_release(drc);
930ef3b5 443 unplug_completed = true;
4f9242fc
DG
444 }
445
4f9242fc 446 if (drc->dev) {
9d4c0f4f
DG
447 /* A device present at reset is ready to go, same as coldplugged */
448 drc->state = drck->ready_state;
188bfe1b
BR
449 /*
450 * Ensure that we are able to send the FDT fragment again
451 * via configure-connector call if the guest requests.
452 */
453 drc->ccs_offset = drc->fdt_start_offset;
454 drc->ccs_depth = 0;
4f9242fc 455 } else {
9d4c0f4f 456 drc->state = drck->empty_state;
188bfe1b
BR
457 drc->ccs_offset = -1;
458 drc->ccs_depth = -1;
bbf5c878 459 }
930ef3b5
GK
460
461 return unplug_completed;
bbf5c878
MR
462}
463
ab858434
GK
464static bool spapr_drc_unplug_requested_needed(void *opaque)
465{
466 return spapr_drc_unplug_requested(opaque);
467}
468
469static const VMStateDescription vmstate_spapr_drc_unplug_requested = {
470 .name = "spapr_drc/unplug_requested",
471 .version_id = 1,
472 .minimum_version_id = 1,
473 .needed = spapr_drc_unplug_requested_needed,
474 .fields = (VMStateField []) {
475 VMSTATE_BOOL(unplug_requested, SpaprDrc),
476 VMSTATE_END_OF_LIST()
477 }
478};
479
cd725bd7 480static bool spapr_drc_needed(void *opaque)
a50919dd 481{
cd725bd7 482 SpaprDrc *drc = opaque;
ce2918cb 483 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
a50919dd 484
4b63db12
GK
485 /*
486 * If no dev is plugged in there is no need to migrate the DRC state
487 * nor to reset the DRC at CAS.
488 */
c618e300 489 if (!drc->dev) {
a50919dd
DHB
490 return false;
491 }
492
493 /*
4b63db12
GK
494 * We need to reset the DRC at CAS or to migrate the DRC state if it's
495 * not equal to the expected long-term state, which is the same as the
ab858434 496 * coldplugged initial state, or if an unplug request is pending.
4b63db12 497 */
ab858434
GK
498 return drc->state != drck->ready_state ||
499 spapr_drc_unplug_requested(drc);
a50919dd
DHB
500}
501
502static const VMStateDescription vmstate_spapr_drc = {
503 .name = "spapr_drc",
504 .version_id = 1,
505 .minimum_version_id = 1,
506 .needed = spapr_drc_needed,
507 .fields = (VMStateField []) {
ce2918cb 508 VMSTATE_UINT32(state, SpaprDrc),
a50919dd 509 VMSTATE_END_OF_LIST()
ab858434
GK
510 },
511 .subsections = (const VMStateDescription * []) {
512 &vmstate_spapr_drc_unplug_requested,
513 NULL
a50919dd
DHB
514 }
515};
516
00f46c92 517static void drc_realize(DeviceState *d, Error **errp)
bbf5c878 518{
ce2918cb 519 SpaprDrc *drc = SPAPR_DR_CONNECTOR(d);
37deca77 520 g_autofree gchar *link_name = g_strdup_printf("%x", spapr_drc_index(drc));
bbf5c878 521 Object *root_container;
7a309cc9 522 const char *child_name;
bbf5c878 523
0b55aa91 524 trace_spapr_drc_realize(spapr_drc_index(drc));
bbf5c878
MR
525 /* NOTE: we do this as part of realize/unrealize due to the fact
526 * that the guest will communicate with the DRC via RTAS calls
527 * referencing the global DRC index. By unlinking the DRC
528 * from DRC_CONTAINER_PATH/<drc_index> we effectively make it
529 * inaccessible by the guest, since lookups rely on this path
530 * existing in the composition tree
531 */
532 root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
bbf5c878 533 child_name = object_get_canonical_path_component(OBJECT(drc));
0b55aa91 534 trace_spapr_drc_realize_child(spapr_drc_index(drc), child_name);
bbf5c878 535 object_property_add_alias(root_container, link_name,
d2623129 536 drc->owner, child_name);
3cad405b 537 vmstate_register(VMSTATE_IF(drc), spapr_drc_index(drc), &vmstate_spapr_drc,
a50919dd 538 drc);
0b55aa91 539 trace_spapr_drc_realize_complete(spapr_drc_index(drc));
bbf5c878
MR
540}
541
00f46c92 542static void drc_unrealize(DeviceState *d)
bbf5c878 543{
ce2918cb 544 SpaprDrc *drc = SPAPR_DR_CONNECTOR(d);
ef2ece4a 545 g_autofree gchar *name = g_strdup_printf("%x", spapr_drc_index(drc));
bbf5c878 546 Object *root_container;
bbf5c878 547
0b55aa91 548 trace_spapr_drc_unrealize(spapr_drc_index(drc));
3cad405b 549 vmstate_unregister(VMSTATE_IF(drc), &vmstate_spapr_drc, drc);
bbf5c878 550 root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
df4fe0b2 551 object_property_del(root_container, name);
bbf5c878
MR
552}
553
ce2918cb 554SpaprDrc *spapr_dr_connector_new(Object *owner, const char *type,
bbf5c878
MR
555 uint32_t id)
556{
ce2918cb 557 SpaprDrc *drc = SPAPR_DR_CONNECTOR(object_new(type));
7614114e 558 g_autofree char *prop_name = NULL;
bbf5c878 559
bbf5c878
MR
560 drc->id = id;
561 drc->owner = owner;
0b55aa91
DG
562 prop_name = g_strdup_printf("dr-connector[%"PRIu32"]",
563 spapr_drc_index(drc));
d2623129 564 object_property_add_child(owner, prop_name, OBJECT(drc));
f3f41030 565 object_unref(OBJECT(drc));
ce189ab2 566 qdev_realize(DEVICE(drc), NULL, NULL);
bbf5c878 567
bbf5c878
MR
568 return drc;
569}
570
571static void spapr_dr_connector_instance_init(Object *obj)
572{
ce2918cb
DG
573 SpaprDrc *drc = SPAPR_DR_CONNECTOR(obj);
574 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
bbf5c878 575
d2623129 576 object_property_add_uint32_ptr(obj, "id", &drc->id, OBJ_PROP_FLAG_READ);
bbf5c878 577 object_property_add(obj, "index", "uint32", prop_get_index,
d2623129 578 NULL, NULL, NULL);
bbf5c878 579 object_property_add(obj, "fdt", "struct", prop_get_fdt,
d2623129 580 NULL, NULL, NULL);
9d4c0f4f 581 drc->state = drck->empty_state;
bbf5c878
MR
582}
583
584static void spapr_dr_connector_class_init(ObjectClass *k, void *data)
585{
586 DeviceClass *dk = DEVICE_CLASS(k);
bbf5c878 587
00f46c92
GK
588 dk->realize = drc_realize;
589 dk->unrealize = drc_unrealize;
c401ae8c 590 /*
eaf1ffbe
GK
591 * Reason: DR connector needs to be wired to either the machine or to a
592 * PHB in spapr_dr_connector_new().
c401ae8c 593 */
e90f2a8c 594 dk->user_creatable = false;
bbf5c878
MR
595}
596
67fea71b
DG
597static bool drc_physical_needed(void *opaque)
598{
ce2918cb
DG
599 SpaprDrcPhysical *drcp = (SpaprDrcPhysical *)opaque;
600 SpaprDrc *drc = SPAPR_DR_CONNECTOR(drcp);
67fea71b
DG
601
602 if ((drc->dev && (drcp->dr_indicator == SPAPR_DR_INDICATOR_ACTIVE))
603 || (!drc->dev && (drcp->dr_indicator == SPAPR_DR_INDICATOR_INACTIVE))) {
604 return false;
605 }
606 return true;
607}
608
609static const VMStateDescription vmstate_spapr_drc_physical = {
610 .name = "spapr_drc/physical",
611 .version_id = 1,
612 .minimum_version_id = 1,
613 .needed = drc_physical_needed,
614 .fields = (VMStateField []) {
ce2918cb 615 VMSTATE_UINT32(dr_indicator, SpaprDrcPhysical),
67fea71b
DG
616 VMSTATE_END_OF_LIST()
617 }
618};
619
620static void drc_physical_reset(void *opaque)
621{
ce2918cb
DG
622 SpaprDrc *drc = SPAPR_DR_CONNECTOR(opaque);
623 SpaprDrcPhysical *drcp = SPAPR_DRC_PHYSICAL(drc);
67fea71b
DG
624
625 if (drc->dev) {
626 drcp->dr_indicator = SPAPR_DR_INDICATOR_ACTIVE;
627 } else {
628 drcp->dr_indicator = SPAPR_DR_INDICATOR_INACTIVE;
629 }
630}
631
632static void realize_physical(DeviceState *d, Error **errp)
633{
ce2918cb 634 SpaprDrcPhysical *drcp = SPAPR_DRC_PHYSICAL(d);
67fea71b
DG
635 Error *local_err = NULL;
636
00f46c92 637 drc_realize(d, &local_err);
67fea71b
DG
638 if (local_err) {
639 error_propagate(errp, local_err);
640 return;
641 }
642
3cad405b
MAL
643 vmstate_register(VMSTATE_IF(drcp),
644 spapr_drc_index(SPAPR_DR_CONNECTOR(drcp)),
67fea71b
DG
645 &vmstate_spapr_drc_physical, drcp);
646 qemu_register_reset(drc_physical_reset, drcp);
647}
648
b69c3c21 649static void unrealize_physical(DeviceState *d)
379ae096 650{
ce2918cb 651 SpaprDrcPhysical *drcp = SPAPR_DRC_PHYSICAL(d);
379ae096 652
00f46c92 653 drc_unrealize(d);
3cad405b 654 vmstate_unregister(VMSTATE_IF(drcp), &vmstate_spapr_drc_physical, drcp);
379ae096
GK
655 qemu_unregister_reset(drc_physical_reset, drcp);
656}
657
f224d35b
DG
658static void spapr_drc_physical_class_init(ObjectClass *k, void *data)
659{
67fea71b 660 DeviceClass *dk = DEVICE_CLASS(k);
ce2918cb 661 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
f224d35b 662
67fea71b 663 dk->realize = realize_physical;
379ae096 664 dk->unrealize = unrealize_physical;
f224d35b 665 drck->dr_entity_sense = physical_entity_sense;
0dfabd39
DG
666 drck->isolate = drc_isolate_physical;
667 drck->unisolate = drc_unisolate_physical;
9d4c0f4f
DG
668 drck->ready_state = SPAPR_DRC_STATE_PHYSICAL_CONFIGURED;
669 drck->empty_state = SPAPR_DRC_STATE_PHYSICAL_POWERON;
f224d35b
DG
670}
671
672static void spapr_drc_logical_class_init(ObjectClass *k, void *data)
673{
ce2918cb 674 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
f224d35b
DG
675
676 drck->dr_entity_sense = logical_entity_sense;
0dfabd39
DG
677 drck->isolate = drc_isolate_logical;
678 drck->unisolate = drc_unisolate_logical;
9d4c0f4f
DG
679 drck->ready_state = SPAPR_DRC_STATE_LOGICAL_CONFIGURED;
680 drck->empty_state = SPAPR_DRC_STATE_LOGICAL_UNUSABLE;
f224d35b
DG
681}
682
2d335818
DG
683static void spapr_drc_cpu_class_init(ObjectClass *k, void *data)
684{
ce2918cb 685 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
2d335818
DG
686
687 drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU;
1693ea16 688 drck->typename = "CPU";
79808336 689 drck->drc_name_prefix = "CPU ";
6b762f29 690 drck->release = spapr_core_release;
345b12b9 691 drck->dt_populate = spapr_core_dt_populate;
2d335818
DG
692}
693
694static void spapr_drc_pci_class_init(ObjectClass *k, void *data)
695{
ce2918cb 696 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
2d335818
DG
697
698 drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI;
1693ea16 699 drck->typename = "28";
79808336 700 drck->drc_name_prefix = "C";
6b762f29 701 drck->release = spapr_phb_remove_pci_device_cb;
46fd0299 702 drck->dt_populate = spapr_pci_dt_populate;
2d335818
DG
703}
704
705static void spapr_drc_lmb_class_init(ObjectClass *k, void *data)
706{
ce2918cb 707 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
2d335818
DG
708
709 drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB;
1693ea16 710 drck->typename = "MEM";
79808336 711 drck->drc_name_prefix = "LMB ";
6b762f29 712 drck->release = spapr_lmb_release;
62d38c9b 713 drck->dt_populate = spapr_lmb_dt_populate;
2d335818
DG
714}
715
962b6c36
MR
716static void spapr_drc_phb_class_init(ObjectClass *k, void *data)
717{
ce2918cb 718 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
962b6c36
MR
719
720 drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB;
721 drck->typename = "PHB";
722 drck->drc_name_prefix = "PHB ";
bb2bdd81
GK
723 drck->release = spapr_phb_release;
724 drck->dt_populate = spapr_phb_dt_populate;
962b6c36
MR
725}
726
ee3a71e3
SB
727static void spapr_drc_pmem_class_init(ObjectClass *k, void *data)
728{
729 SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
730
731 drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_PMEM;
732 drck->typename = "PMEM";
733 drck->drc_name_prefix = "PMEM ";
734 drck->release = NULL;
735 drck->dt_populate = spapr_pmem_dt_populate;
736}
737
bbf5c878
MR
738static const TypeInfo spapr_dr_connector_info = {
739 .name = TYPE_SPAPR_DR_CONNECTOR,
740 .parent = TYPE_DEVICE,
ce2918cb 741 .instance_size = sizeof(SpaprDrc),
bbf5c878 742 .instance_init = spapr_dr_connector_instance_init,
ce2918cb 743 .class_size = sizeof(SpaprDrcClass),
bbf5c878 744 .class_init = spapr_dr_connector_class_init,
2d335818
DG
745 .abstract = true,
746};
747
748static const TypeInfo spapr_drc_physical_info = {
749 .name = TYPE_SPAPR_DRC_PHYSICAL,
750 .parent = TYPE_SPAPR_DR_CONNECTOR,
ce2918cb 751 .instance_size = sizeof(SpaprDrcPhysical),
f224d35b 752 .class_init = spapr_drc_physical_class_init,
2d335818
DG
753 .abstract = true,
754};
755
756static const TypeInfo spapr_drc_logical_info = {
757 .name = TYPE_SPAPR_DRC_LOGICAL,
758 .parent = TYPE_SPAPR_DR_CONNECTOR,
f224d35b 759 .class_init = spapr_drc_logical_class_init,
2d335818
DG
760 .abstract = true,
761};
762
763static const TypeInfo spapr_drc_cpu_info = {
764 .name = TYPE_SPAPR_DRC_CPU,
765 .parent = TYPE_SPAPR_DRC_LOGICAL,
2d335818
DG
766 .class_init = spapr_drc_cpu_class_init,
767};
768
769static const TypeInfo spapr_drc_pci_info = {
770 .name = TYPE_SPAPR_DRC_PCI,
771 .parent = TYPE_SPAPR_DRC_PHYSICAL,
2d335818
DG
772 .class_init = spapr_drc_pci_class_init,
773};
774
775static const TypeInfo spapr_drc_lmb_info = {
776 .name = TYPE_SPAPR_DRC_LMB,
777 .parent = TYPE_SPAPR_DRC_LOGICAL,
2d335818 778 .class_init = spapr_drc_lmb_class_init,
bbf5c878
MR
779};
780
962b6c36
MR
781static const TypeInfo spapr_drc_phb_info = {
782 .name = TYPE_SPAPR_DRC_PHB,
783 .parent = TYPE_SPAPR_DRC_LOGICAL,
ce2918cb 784 .instance_size = sizeof(SpaprDrc),
962b6c36
MR
785 .class_init = spapr_drc_phb_class_init,
786};
787
ee3a71e3
SB
788static const TypeInfo spapr_drc_pmem_info = {
789 .name = TYPE_SPAPR_DRC_PMEM,
790 .parent = TYPE_SPAPR_DRC_LOGICAL,
791 .class_init = spapr_drc_pmem_class_init,
792};
793
bbf5c878
MR
794/* helper functions for external users */
795
ce2918cb 796SpaprDrc *spapr_drc_by_index(uint32_t index)
bbf5c878
MR
797{
798 Object *obj;
5436eee1
DHB
799 g_autofree gchar *name = g_strdup_printf("%s/%x", DRC_CONTAINER_PATH,
800 index);
bbf5c878
MR
801 obj = object_resolve_path(name, NULL);
802
803 return !obj ? NULL : SPAPR_DR_CONNECTOR(obj);
804}
805
ce2918cb 806SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id)
bbf5c878 807{
ce2918cb 808 SpaprDrcClass *drck
fbf55397
DG
809 = SPAPR_DR_CONNECTOR_CLASS(object_class_by_name(type));
810
811 return spapr_drc_by_index(drck->typeshift << DRC_INDEX_TYPE_SHIFT
812 | (id & DRC_INDEX_ID_MASK));
bbf5c878 813}
e4b798bb 814
e4b798bb 815/**
9e7d38e8 816 * spapr_dt_drc
e4b798bb
MR
817 *
818 * @fdt: libfdt device tree
819 * @path: path in the DT to generate properties
820 * @owner: parent Object/DeviceState for which to generate DRC
821 * descriptions for
ce2918cb 822 * @drc_type_mask: mask of SpaprDrcType values corresponding
e4b798bb
MR
823 * to the types of DRCs to generate entries for
824 *
825 * generate OF properties to describe DRC topology/indices to guests
826 *
827 * as documented in PAPR+ v2.1, 13.5.2
828 */
9e7d38e8 829int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask)
e4b798bb
MR
830{
831 Object *root_container;
832 ObjectProperty *prop;
7746abd8 833 ObjectPropertyIterator iter;
e4b798bb 834 uint32_t drc_count = 0;
75610acf
DHB
835 g_autoptr(GArray) drc_indexes = g_array_new(false, true,
836 sizeof(uint32_t));
837 g_autoptr(GArray) drc_power_domains = g_array_new(false, true,
838 sizeof(uint32_t));
839 g_autoptr(GString) drc_names = g_string_set_size(g_string_new(NULL),
840 sizeof(uint32_t));
841 g_autoptr(GString) drc_types = g_string_set_size(g_string_new(NULL),
842 sizeof(uint32_t));
e4b798bb
MR
843 int ret;
844
776e887f
GK
845 /*
846 * This should really be only called once per node since it overwrites
847 * the OF properties if they already exist.
848 */
849 g_assert(!fdt_get_property(fdt, offset, "ibm,drc-indexes", NULL));
850
e4b798bb
MR
851 /* the first entry of each properties is a 32-bit integer encoding
852 * the number of elements in the array. we won't know this until
853 * we complete the iteration through all the matching DRCs, but
854 * reserve the space now and set the offsets accordingly so we
855 * can fill them in later.
856 */
e4b798bb 857 drc_indexes = g_array_set_size(drc_indexes, 1);
e4b798bb 858 drc_power_domains = g_array_set_size(drc_power_domains, 1);
e4b798bb
MR
859
860 /* aliases for all DRConnector objects will be rooted in QOM
861 * composition tree at DRC_CONTAINER_PATH
862 */
863 root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
864
7746abd8
DB
865 object_property_iter_init(&iter, root_container);
866 while ((prop = object_property_iter_next(&iter))) {
e4b798bb 867 Object *obj;
ce2918cb
DG
868 SpaprDrc *drc;
869 SpaprDrcClass *drck;
75610acf 870 g_autofree char *drc_name = NULL;
e4b798bb
MR
871 uint32_t drc_index, drc_power_domain;
872
873 if (!strstart(prop->type, "link<", NULL)) {
874 continue;
875 }
876
552d7f49
MA
877 obj = object_property_get_link(root_container, prop->name,
878 &error_abort);
e4b798bb
MR
879 drc = SPAPR_DR_CONNECTOR(obj);
880 drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
881
882 if (owner && (drc->owner != owner)) {
883 continue;
884 }
885
2d335818 886 if ((spapr_drc_type(drc) & drc_type_mask) == 0) {
e4b798bb
MR
887 continue;
888 }
889
890 drc_count++;
891
892 /* ibm,drc-indexes */
0b55aa91 893 drc_index = cpu_to_be32(spapr_drc_index(drc));
e4b798bb
MR
894 g_array_append_val(drc_indexes, drc_index);
895
896 /* ibm,drc-power-domains */
897 drc_power_domain = cpu_to_be32(-1);
898 g_array_append_val(drc_power_domains, drc_power_domain);
899
900 /* ibm,drc-names */
dbd26f2f
SB
901 drc_name = spapr_drc_name(drc);
902 drc_names = g_string_append(drc_names, drc_name);
e4b798bb
MR
903 drc_names = g_string_insert_len(drc_names, -1, "\0", 1);
904
905 /* ibm,drc-types */
1693ea16 906 drc_types = g_string_append(drc_types, drck->typename);
e4b798bb
MR
907 drc_types = g_string_insert_len(drc_types, -1, "\0", 1);
908 }
909
910 /* now write the drc count into the space we reserved at the
911 * beginning of the arrays previously
912 */
913 *(uint32_t *)drc_indexes->data = cpu_to_be32(drc_count);
914 *(uint32_t *)drc_power_domains->data = cpu_to_be32(drc_count);
915 *(uint32_t *)drc_names->str = cpu_to_be32(drc_count);
916 *(uint32_t *)drc_types->str = cpu_to_be32(drc_count);
917
9e7d38e8 918 ret = fdt_setprop(fdt, offset, "ibm,drc-indexes",
e4b798bb
MR
919 drc_indexes->data,
920 drc_indexes->len * sizeof(uint32_t));
921 if (ret) {
ce9863b7 922 error_report("Couldn't create ibm,drc-indexes property");
75610acf 923 return ret;
e4b798bb
MR
924 }
925
9e7d38e8 926 ret = fdt_setprop(fdt, offset, "ibm,drc-power-domains",
e4b798bb
MR
927 drc_power_domains->data,
928 drc_power_domains->len * sizeof(uint32_t));
929 if (ret) {
ce9863b7 930 error_report("Couldn't finalize ibm,drc-power-domains property");
75610acf 931 return ret;
e4b798bb
MR
932 }
933
9e7d38e8 934 ret = fdt_setprop(fdt, offset, "ibm,drc-names",
e4b798bb
MR
935 drc_names->str, drc_names->len);
936 if (ret) {
ce9863b7 937 error_report("Couldn't finalize ibm,drc-names property");
75610acf 938 return ret;
e4b798bb
MR
939 }
940
9e7d38e8 941 ret = fdt_setprop(fdt, offset, "ibm,drc-types",
e4b798bb
MR
942 drc_types->str, drc_types->len);
943 if (ret) {
ce9863b7 944 error_report("Couldn't finalize ibm,drc-types property");
e4b798bb
MR
945 }
946
e4b798bb
MR
947 return ret;
948}
b89b3d39 949
babb819f
GK
950void spapr_drc_reset_all(SpaprMachineState *spapr)
951{
952 Object *drc_container;
953 ObjectProperty *prop;
954 ObjectPropertyIterator iter;
955
956 drc_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
957restart:
958 object_property_iter_init(&iter, drc_container);
959 while ((prop = object_property_iter_next(&iter))) {
960 SpaprDrc *drc;
961
962 if (!strstart(prop->type, "link<", NULL)) {
963 continue;
964 }
965 drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container,
966 prop->name,
967 &error_abort));
968
969 /*
970 * This will complete any pending plug/unplug requests.
971 * In case of a unplugged PHB or PCI bridge, this will
972 * cause some DRCs to be destroyed and thus potentially
973 * invalidate the iterator.
974 */
975 if (spapr_drc_reset(drc)) {
976 goto restart;
977 }
978 }
979}
980
b89b3d39
DG
981/*
982 * RTAS calls
983 */
984
7b7258f8 985static uint32_t rtas_set_isolation_state(uint32_t idx, uint32_t state)
b89b3d39 986{
ce2918cb
DG
987 SpaprDrc *drc = spapr_drc_by_index(idx);
988 SpaprDrcClass *drck;
7b7258f8
DG
989
990 if (!drc) {
0dfabd39 991 return RTAS_OUT_NO_SUCH_INDICATOR;
b89b3d39
DG
992 }
993
0dfabd39
DG
994 trace_spapr_drc_set_isolation_state(spapr_drc_index(drc), state);
995
7b7258f8 996 drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
0dfabd39
DG
997
998 switch (state) {
999 case SPAPR_DR_ISOLATION_STATE_ISOLATED:
1000 return drck->isolate(drc);
1001
1002 case SPAPR_DR_ISOLATION_STATE_UNISOLATED:
1003 return drck->unisolate(drc);
1004
1005 default:
1006 return RTAS_OUT_PARAM_ERROR;
1007 }
b89b3d39
DG
1008}
1009
7b7258f8 1010static uint32_t rtas_set_allocation_state(uint32_t idx, uint32_t state)
b89b3d39 1011{
ce2918cb 1012 SpaprDrc *drc = spapr_drc_by_index(idx);
b89b3d39 1013
61736732
DG
1014 if (!drc || !object_dynamic_cast(OBJECT(drc), TYPE_SPAPR_DRC_LOGICAL)) {
1015 return RTAS_OUT_NO_SUCH_INDICATOR;
b89b3d39
DG
1016 }
1017
61736732
DG
1018 trace_spapr_drc_set_allocation_state(spapr_drc_index(drc), state);
1019
1020 switch (state) {
1021 case SPAPR_DR_ALLOCATION_STATE_USABLE:
1022 return drc_set_usable(drc);
1023
1024 case SPAPR_DR_ALLOCATION_STATE_UNUSABLE:
1025 return drc_set_unusable(drc);
1026
1027 default:
1028 return RTAS_OUT_PARAM_ERROR;
1029 }
7b7258f8 1030}
b89b3d39 1031
cd74d27e 1032static uint32_t rtas_set_dr_indicator(uint32_t idx, uint32_t state)
7b7258f8 1033{
ce2918cb 1034 SpaprDrc *drc = spapr_drc_by_index(idx);
b89b3d39 1035
67fea71b
DG
1036 if (!drc || !object_dynamic_cast(OBJECT(drc), TYPE_SPAPR_DRC_PHYSICAL)) {
1037 return RTAS_OUT_NO_SUCH_INDICATOR;
1038 }
1039 if ((state != SPAPR_DR_INDICATOR_INACTIVE)
1040 && (state != SPAPR_DR_INDICATOR_ACTIVE)
1041 && (state != SPAPR_DR_INDICATOR_IDENTIFY)
1042 && (state != SPAPR_DR_INDICATOR_ACTION)) {
1043 return RTAS_OUT_PARAM_ERROR; /* bad state parameter */
7b7258f8
DG
1044 }
1045
cd74d27e 1046 trace_spapr_drc_set_dr_indicator(idx, state);
67fea71b 1047 SPAPR_DRC_PHYSICAL(drc)->dr_indicator = state;
cd74d27e 1048 return RTAS_OUT_SUCCESS;
7b7258f8
DG
1049}
1050
ce2918cb 1051static void rtas_set_indicator(PowerPCCPU *cpu, SpaprMachineState *spapr,
7b7258f8
DG
1052 uint32_t token,
1053 uint32_t nargs, target_ulong args,
1054 uint32_t nret, target_ulong rets)
1055{
1056 uint32_t type, idx, state;
1057 uint32_t ret = RTAS_OUT_SUCCESS;
1058
1059 if (nargs != 3 || nret != 1) {
b89b3d39
DG
1060 ret = RTAS_OUT_PARAM_ERROR;
1061 goto out;
1062 }
b89b3d39 1063
7b7258f8
DG
1064 type = rtas_ld(args, 0);
1065 idx = rtas_ld(args, 1);
1066 state = rtas_ld(args, 2);
1067
1068 switch (type) {
b89b3d39 1069 case RTAS_SENSOR_TYPE_ISOLATION_STATE:
7b7258f8 1070 ret = rtas_set_isolation_state(idx, state);
b89b3d39
DG
1071 break;
1072 case RTAS_SENSOR_TYPE_DR:
cd74d27e 1073 ret = rtas_set_dr_indicator(idx, state);
b89b3d39
DG
1074 break;
1075 case RTAS_SENSOR_TYPE_ALLOCATION_STATE:
7b7258f8 1076 ret = rtas_set_allocation_state(idx, state);
b89b3d39
DG
1077 break;
1078 default:
7b7258f8 1079 ret = RTAS_OUT_NOT_SUPPORTED;
b89b3d39
DG
1080 }
1081
1082out:
1083 rtas_st(rets, 0, ret);
b89b3d39
DG
1084}
1085
ce2918cb 1086static void rtas_get_sensor_state(PowerPCCPU *cpu, SpaprMachineState *spapr,
b89b3d39
DG
1087 uint32_t token, uint32_t nargs,
1088 target_ulong args, uint32_t nret,
1089 target_ulong rets)
1090{
1091 uint32_t sensor_type;
1092 uint32_t sensor_index;
1093 uint32_t sensor_state = 0;
ce2918cb
DG
1094 SpaprDrc *drc;
1095 SpaprDrcClass *drck;
b89b3d39
DG
1096 uint32_t ret = RTAS_OUT_SUCCESS;
1097
1098 if (nargs != 2 || nret != 2) {
1099 ret = RTAS_OUT_PARAM_ERROR;
1100 goto out;
1101 }
1102
1103 sensor_type = rtas_ld(args, 0);
1104 sensor_index = rtas_ld(args, 1);
1105
1106 if (sensor_type != RTAS_SENSOR_TYPE_ENTITY_SENSE) {
1107 /* currently only DR-related sensors are implemented */
1108 trace_spapr_rtas_get_sensor_state_not_supported(sensor_index,
1109 sensor_type);
1110 ret = RTAS_OUT_NOT_SUPPORTED;
1111 goto out;
1112 }
1113
fbf55397 1114 drc = spapr_drc_by_index(sensor_index);
b89b3d39
DG
1115 if (!drc) {
1116 trace_spapr_rtas_get_sensor_state_invalid(sensor_index);
1117 ret = RTAS_OUT_PARAM_ERROR;
1118 goto out;
1119 }
1120 drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
f224d35b 1121 sensor_state = drck->dr_entity_sense(drc);
b89b3d39
DG
1122
1123out:
1124 rtas_st(rets, 0, ret);
1125 rtas_st(rets, 1, sensor_state);
1126}
1127
1128/* configure-connector work area offsets, int32_t units for field
1129 * indexes, bytes for field offset/len values.
1130 *
1131 * as documented by PAPR+ v2.7, 13.5.3.5
1132 */
1133#define CC_IDX_NODE_NAME_OFFSET 2
1134#define CC_IDX_PROP_NAME_OFFSET 2
1135#define CC_IDX_PROP_LEN 3
1136#define CC_IDX_PROP_DATA_OFFSET 4
1137#define CC_VAL_DATA_OFFSET ((CC_IDX_PROP_DATA_OFFSET + 1) * 4)
1138#define CC_WA_LEN 4096
1139
1140static void configure_connector_st(target_ulong addr, target_ulong offset,
1141 const void *buf, size_t len)
1142{
1143 cpu_physical_memory_write(ppc64_phys_to_real(addr + offset),
1144 buf, MIN(len, CC_WA_LEN - offset));
1145}
1146
b89b3d39 1147static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
ce2918cb 1148 SpaprMachineState *spapr,
b89b3d39
DG
1149 uint32_t token, uint32_t nargs,
1150 target_ulong args, uint32_t nret,
1151 target_ulong rets)
1152{
1153 uint64_t wa_addr;
1154 uint64_t wa_offset;
1155 uint32_t drc_index;
ce2918cb
DG
1156 SpaprDrc *drc;
1157 SpaprDrcClass *drck;
1158 SpaprDRCCResponse resp = SPAPR_DR_CC_RESPONSE_CONTINUE;
b89b3d39 1159 int rc;
b89b3d39
DG
1160
1161 if (nargs != 2 || nret != 1) {
1162 rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
1163 return;
1164 }
1165
1166 wa_addr = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 0);
1167
1168 drc_index = rtas_ld(wa_addr, 0);
fbf55397 1169 drc = spapr_drc_by_index(drc_index);
b89b3d39
DG
1170 if (!drc) {
1171 trace_spapr_rtas_ibm_configure_connector_invalid(drc_index);
1172 rc = RTAS_OUT_PARAM_ERROR;
1173 goto out;
1174 }
1175
9d4c0f4f 1176 if ((drc->state != SPAPR_DRC_STATE_LOGICAL_UNISOLATE)
188bfe1b
BR
1177 && (drc->state != SPAPR_DRC_STATE_PHYSICAL_UNISOLATE)
1178 && (drc->state != SPAPR_DRC_STATE_LOGICAL_CONFIGURED)
1179 && (drc->state != SPAPR_DRC_STATE_PHYSICAL_CONFIGURED)) {
1180 /*
1181 * Need to unisolate the device before configuring
1182 * or it should already be in configured state to
1183 * allow configure-connector be called repeatedly.
1184 */
b89b3d39
DG
1185 rc = SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE;
1186 goto out;
1187 }
1188
9d4c0f4f
DG
1189 drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
1190
fe1831ef
DHB
1191 /*
1192 * This indicates that the kernel is reconfiguring a LMB due to
eb7f80fd 1193 * a failed hotunplug. Rollback the DIMM unplug process.
fe1831ef
DHB
1194 */
1195 if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB &&
1196 drc->unplug_requested) {
eb7f80fd 1197 spapr_memory_unplug_rollback(spapr, drc->dev);
fe1831ef
DHB
1198 }
1199
d9c95c71 1200 if (!drc->fdt) {
d9c95c71
GK
1201 void *fdt;
1202 int fdt_size;
1203
1204 fdt = create_device_tree(&fdt_size);
1205
1206 if (drck->dt_populate(drc, spapr, fdt, &drc->fdt_start_offset,
9261ef5e 1207 NULL)) {
d9c95c71 1208 g_free(fdt);
d9c95c71
GK
1209 rc = SPAPR_DR_CC_RESPONSE_ERROR;
1210 goto out;
1211 }
1212
1213 drc->fdt = fdt;
1214 drc->ccs_offset = drc->fdt_start_offset;
1215 drc->ccs_depth = 0;
1216 }
1217
b89b3d39
DG
1218 do {
1219 uint32_t tag;
1220 const char *name;
1221 const struct fdt_property *prop;
1222 int fdt_offset_next, prop_len;
1223
4445b1d2 1224 tag = fdt_next_tag(drc->fdt, drc->ccs_offset, &fdt_offset_next);
b89b3d39
DG
1225
1226 switch (tag) {
1227 case FDT_BEGIN_NODE:
4445b1d2
DG
1228 drc->ccs_depth++;
1229 name = fdt_get_name(drc->fdt, drc->ccs_offset, NULL);
b89b3d39
DG
1230
1231 /* provide the name of the next OF node */
1232 wa_offset = CC_VAL_DATA_OFFSET;
1233 rtas_st(wa_addr, CC_IDX_NODE_NAME_OFFSET, wa_offset);
1234 configure_connector_st(wa_addr, wa_offset, name, strlen(name) + 1);
1235 resp = SPAPR_DR_CC_RESPONSE_NEXT_CHILD;
1236 break;
1237 case FDT_END_NODE:
4445b1d2
DG
1238 drc->ccs_depth--;
1239 if (drc->ccs_depth == 0) {
0b55aa91 1240 uint32_t drc_index = spapr_drc_index(drc);
9d4c0f4f
DG
1241
1242 /* done sending the device tree, move to configured state */
0b55aa91 1243 trace_spapr_drc_set_configured(drc_index);
9d4c0f4f 1244 drc->state = drck->ready_state;
188bfe1b
BR
1245 /*
1246 * Ensure that we are able to send the FDT fragment
1247 * again via configure-connector call if the guest requests.
1248 */
1249 drc->ccs_offset = drc->fdt_start_offset;
1250 drc->ccs_depth = 0;
1251 fdt_offset_next = drc->fdt_start_offset;
b89b3d39
DG
1252 resp = SPAPR_DR_CC_RESPONSE_SUCCESS;
1253 } else {
1254 resp = SPAPR_DR_CC_RESPONSE_PREV_PARENT;
1255 }
1256 break;
1257 case FDT_PROP:
4445b1d2 1258 prop = fdt_get_property_by_offset(drc->fdt, drc->ccs_offset,
b89b3d39 1259 &prop_len);
88af6ea5 1260 name = fdt_string(drc->fdt, fdt32_to_cpu(prop->nameoff));
b89b3d39
DG
1261
1262 /* provide the name of the next OF property */
1263 wa_offset = CC_VAL_DATA_OFFSET;
1264 rtas_st(wa_addr, CC_IDX_PROP_NAME_OFFSET, wa_offset);
1265 configure_connector_st(wa_addr, wa_offset, name, strlen(name) + 1);
1266
1267 /* provide the length and value of the OF property. data gets
1268 * placed immediately after NULL terminator of the OF property's
1269 * name string
1270 */
1271 wa_offset += strlen(name) + 1,
1272 rtas_st(wa_addr, CC_IDX_PROP_LEN, prop_len);
1273 rtas_st(wa_addr, CC_IDX_PROP_DATA_OFFSET, wa_offset);
1274 configure_connector_st(wa_addr, wa_offset, prop->data, prop_len);
1275 resp = SPAPR_DR_CC_RESPONSE_NEXT_PROPERTY;
1276 break;
1277 case FDT_END:
1278 resp = SPAPR_DR_CC_RESPONSE_ERROR;
1279 default:
1280 /* keep seeking for an actionable tag */
1281 break;
1282 }
4445b1d2
DG
1283 if (drc->ccs_offset >= 0) {
1284 drc->ccs_offset = fdt_offset_next;
b89b3d39
DG
1285 }
1286 } while (resp == SPAPR_DR_CC_RESPONSE_CONTINUE);
1287
1288 rc = resp;
1289out:
1290 rtas_st(rets, 0, rc);
1291}
1292
1293static void spapr_drc_register_types(void)
1294{
1295 type_register_static(&spapr_dr_connector_info);
2d335818
DG
1296 type_register_static(&spapr_drc_physical_info);
1297 type_register_static(&spapr_drc_logical_info);
1298 type_register_static(&spapr_drc_cpu_info);
1299 type_register_static(&spapr_drc_pci_info);
1300 type_register_static(&spapr_drc_lmb_info);
962b6c36 1301 type_register_static(&spapr_drc_phb_info);
ee3a71e3 1302 type_register_static(&spapr_drc_pmem_info);
b89b3d39
DG
1303
1304 spapr_rtas_register(RTAS_SET_INDICATOR, "set-indicator",
1305 rtas_set_indicator);
1306 spapr_rtas_register(RTAS_GET_SENSOR_STATE, "get-sensor-state",
1307 rtas_get_sensor_state);
1308 spapr_rtas_register(RTAS_IBM_CONFIGURE_CONNECTOR, "ibm,configure-connector",
1309 rtas_ibm_configure_connector);
1310}
1311type_init(spapr_drc_register_types)