As a rough outline for a pnv-phb device, I'd aim for creating a proxy for the 
underlying device rather than manually invoking the QOM instance and 
qdev-related functions:


struct PnvPHB {
     ....
     uint32_t version;
     Object *phb_dev;  /* Could be PHBCommonBase if it exists */
};

DECLARE_SIMPLE_OBJECT_TYPE(...)

...
...

static Property pnv_phb_properties[] = {
     DEFINE_PROP_UINT32("version", PnvPHB, version, 0),

It could be the type name directly.

     DEFINE_PROP_END_OF_LIST(),
};

static void pnv_phb_realize(DeviceState *dev, Error **errp)
{
     PnvPHB *pnv_phb = PNV_PHB(dev);
     g_autofree char *phb_typename;

     if (!pnv_phb->version) {
         error_setg("version not specified", errp);
         return;
     }

     switch (pnv_phb->version) {
     case 3:
         phb_typename = g_strdup(TYPE_PNV_PHB3);
         break;
     case 4:
         phb_typename = g_strdup(TYPE_PNV_PHB4);
         break;
     default:
         g_assert_unreached();
     }

     pnv_phb->phb_dev = object_new(phb_typename);
     object_property_add_child(OBJECT(dev), "phb-device", pnv_phb->phb_dev);

     if (!qdev_realize(DEVICE(pnv_phb->phb_dev), errp)) {
         return;
     }

     /* Passthrough child device properties to the proxy device */
     qdev_alias_all_properties(dev, OBJECT(pnv_phb->phb_dev));
}

Finally you can set the pnv-phb version on a per-machine basis by adding the 
version to the machine compat_props:

static GlobalProperty compat[] = {
     { TYPE_PHB_PNV, "version", 3},
};



That looks nice. Something to try for cold plugging phbs on the machine.

Thanks,

C.


Reply via email to