aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc/spapr_drc.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/ppc/spapr_drc.c')
-rw-r--r--hw/ppc/spapr_drc.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 2edb7d1e9c..2943cf47d4 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -22,6 +22,7 @@
#include "qemu/error-report.h"
#include "hw/ppc/spapr.h" /* for RTAS return codes */
#include "hw/pci-host/spapr.h" /* spapr_phb_remove_pci_device_cb callback */
+#include "sysemu/device_tree.h"
#include "trace.h"
#define DRC_CONTAINER_PATH "/dr-connector"
@@ -373,8 +374,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
} while (fdt_depth != 0);
}
-void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
- int fdt_start_offset, Error **errp)
+void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
{
trace_spapr_drc_attach(spapr_drc_index(drc));
@@ -384,11 +384,8 @@ void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
}
g_assert((drc->state == SPAPR_DRC_STATE_LOGICAL_UNUSABLE)
|| (drc->state == SPAPR_DRC_STATE_PHYSICAL_POWERON));
- g_assert(fdt);
drc->dev = d;
- drc->fdt = fdt;
- drc->fdt_start_offset = fdt_start_offset;
object_property_add_link(OBJECT(drc), "device",
object_get_typename(OBJECT(drc->dev)),
@@ -674,6 +671,7 @@ static void spapr_drc_cpu_class_init(ObjectClass *k, void *data)
drck->typename = "CPU";
drck->drc_name_prefix = "CPU ";
drck->release = spapr_core_release;
+ drck->dt_populate = spapr_core_dt_populate;
}
static void spapr_drc_pci_class_init(ObjectClass *k, void *data)
@@ -684,6 +682,7 @@ static void spapr_drc_pci_class_init(ObjectClass *k, void *data)
drck->typename = "28";
drck->drc_name_prefix = "C";
drck->release = spapr_phb_remove_pci_device_cb;
+ drck->dt_populate = spapr_pci_dt_populate;
}
static void spapr_drc_lmb_class_init(ObjectClass *k, void *data)
@@ -694,6 +693,18 @@ static void spapr_drc_lmb_class_init(ObjectClass *k, void *data)
drck->typename = "MEM";
drck->drc_name_prefix = "LMB ";
drck->release = spapr_lmb_release;
+ drck->dt_populate = spapr_lmb_dt_populate;
+}
+
+static void spapr_drc_phb_class_init(ObjectClass *k, void *data)
+{
+ sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
+
+ drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB;
+ drck->typename = "PHB";
+ drck->drc_name_prefix = "PHB ";
+ drck->release = spapr_phb_release;
+ drck->dt_populate = spapr_phb_dt_populate;
}
static const TypeInfo spapr_dr_connector_info = {
@@ -739,6 +750,13 @@ static const TypeInfo spapr_drc_lmb_info = {
.class_init = spapr_drc_lmb_class_init,
};
+static const TypeInfo spapr_drc_phb_info = {
+ .name = TYPE_SPAPR_DRC_PHB,
+ .parent = TYPE_SPAPR_DRC_LOGICAL,
+ .instance_size = sizeof(sPAPRDRConnector),
+ .class_init = spapr_drc_phb_class_init,
+};
+
/* helper functions for external users */
sPAPRDRConnector *spapr_drc_by_index(uint32_t index)
@@ -1102,10 +1120,28 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
goto out;
}
- g_assert(drc->fdt);
-
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ if (!drc->fdt) {
+ Error *local_err = NULL;
+ void *fdt;
+ int fdt_size;
+
+ fdt = create_device_tree(&fdt_size);
+
+ if (drck->dt_populate(drc, spapr, fdt, &drc->fdt_start_offset,
+ &local_err)) {
+ g_free(fdt);
+ error_free(local_err);
+ rc = SPAPR_DR_CC_RESPONSE_ERROR;
+ goto out;
+ }
+
+ drc->fdt = fdt;
+ drc->ccs_offset = drc->fdt_start_offset;
+ drc->ccs_depth = 0;
+ }
+
do {
uint32_t tag;
const char *name;
@@ -1189,6 +1225,7 @@ static void spapr_drc_register_types(void)
type_register_static(&spapr_drc_cpu_info);
type_register_static(&spapr_drc_pci_info);
type_register_static(&spapr_drc_lmb_info);
+ type_register_static(&spapr_drc_phb_info);
spapr_rtas_register(RTAS_SET_INDICATOR, "set-indicator",
rtas_set_indicator);