diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/spapr_llan.c | 37 | ||||
-rw-r--r-- | hw/spapr_vio.c | 55 | ||||
-rw-r--r-- | hw/spapr_vio.h | 35 | ||||
-rw-r--r-- | hw/spapr_vscsi.c | 35 | ||||
-rw-r--r-- | hw/spapr_vty.c | 35 |
5 files changed, 126 insertions, 71 deletions
diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c index b9a5afccbc..0fb176abad 100644 --- a/hw/spapr_llan.c +++ b/hw/spapr_llan.c @@ -474,20 +474,29 @@ static target_ulong h_multicast_ctrl(CPUState *env, sPAPREnvironment *spapr, return H_SUCCESS; } -static VIOsPAPRDeviceInfo spapr_vlan_info = { - .init = spapr_vlan_init, - .devnode = spapr_vlan_devnode, - .dt_name = "l-lan", - .dt_type = "network", - .dt_compatible = "IBM,l-lan", - .signal_mask = 0x1, - .qdev.name = "spapr-vlan", - .qdev.size = sizeof(VIOsPAPRVLANDevice), - .qdev.props = (Property[]) { - DEFINE_SPAPR_PROPERTIES(VIOsPAPRVLANDevice, sdev, 0x1000, 0x10000000), - DEFINE_NIC_PROPERTIES(VIOsPAPRVLANDevice, nicconf), - DEFINE_PROP_END_OF_LIST(), - }, +static Property spapr_vlan_properties[] = { + DEFINE_SPAPR_PROPERTIES(VIOsPAPRVLANDevice, sdev, 0x1000, 0x10000000), + DEFINE_NIC_PROPERTIES(VIOsPAPRVLANDevice, nicconf), + DEFINE_PROP_END_OF_LIST(), +}; + +static void spapr_vlan_class_init(ObjectClass *klass, void *data) +{ + VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass); + + k->init = spapr_vlan_init; + k->devnode = spapr_vlan_devnode; + k->dt_name = "l-lan"; + k->dt_type = "network"; + k->dt_compatible = "IBM,l-lan"; + k->signal_mask = 0x1; +} + +static DeviceInfo spapr_vlan_info = { + .name = "spapr-vlan", + .size = sizeof(VIOsPAPRVLANDevice), + .props = spapr_vlan_properties, + .class_init = spapr_vlan_class_init, }; static void spapr_vlan_register(void) diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c index 015941353e..bc586bfb46 100644 --- a/hw/spapr_vio.c +++ b/hw/spapr_vio.c @@ -75,11 +75,11 @@ VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg) static char *vio_format_dev_name(VIOsPAPRDevice *dev) { - VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qdev_get_info(&dev->qdev); + VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev); char *name; /* Device tree style name device@reg */ - if (asprintf(&name, "%s@%x", info->dt_name, dev->reg) < 0) { + if (asprintf(&name, "%s@%x", pc->dt_name, dev->reg) < 0) { return NULL; } @@ -90,7 +90,7 @@ static char *vio_format_dev_name(VIOsPAPRDevice *dev) static int vio_make_devnode(VIOsPAPRDevice *dev, void *fdt) { - VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qdev_get_info(&dev->qdev); + VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev); int vdevice_off, node_off, ret; char *dt_name; @@ -115,17 +115,17 @@ static int vio_make_devnode(VIOsPAPRDevice *dev, return ret; } - if (info->dt_type) { + if (pc->dt_type) { ret = fdt_setprop_string(fdt, node_off, "device_type", - info->dt_type); + pc->dt_type); if (ret < 0) { return ret; } } - if (info->dt_compatible) { + if (pc->dt_compatible) { ret = fdt_setprop_string(fdt, node_off, "compatible", - info->dt_compatible); + pc->dt_compatible); if (ret < 0) { return ret; } @@ -163,8 +163,8 @@ static int vio_make_devnode(VIOsPAPRDevice *dev, } } - if (info->devnode) { - ret = (info->devnode)(dev, fdt, node_off); + if (pc->devnode) { + ret = (pc->devnode)(dev, fdt, node_off); if (ret < 0) { return ret; } @@ -621,7 +621,7 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token, rtas_st(rets, 0, 0); } -static int spapr_vio_check_reg(VIOsPAPRDevice *sdev, VIOsPAPRDeviceInfo *info) +static int spapr_vio_check_reg(VIOsPAPRDevice *sdev) { VIOsPAPRDevice *other_sdev; DeviceState *qdev; @@ -639,7 +639,9 @@ static int spapr_vio_check_reg(VIOsPAPRDevice *sdev, VIOsPAPRDeviceInfo *info) if (other_sdev != sdev && other_sdev->reg == sdev->reg) { fprintf(stderr, "vio: %s and %s devices conflict at address %#x\n", - info->qdev.name, other_sdev->qdev.info->name, sdev->reg); + object_get_typename(OBJECT(sdev)), + object_get_typename(OBJECT(qdev)), + sdev->reg); return -EEXIST; } } @@ -649,12 +651,12 @@ static int spapr_vio_check_reg(VIOsPAPRDevice *sdev, VIOsPAPRDeviceInfo *info) static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo) { - VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo; VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev; + VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev); char *id; int ret; - ret = spapr_vio_check_reg(dev, info); + ret = spapr_vio_check_reg(dev); if (ret) { return ret; } @@ -675,16 +677,16 @@ static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo) rtce_init(dev); - return info->init(dev); + return pc->init(dev); } -void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info) +void spapr_vio_bus_register_withprop(DeviceInfo *info) { - info->qdev.init = spapr_vio_busdev_init; - info->qdev.bus_info = &spapr_vio_bus_info; + info->init = spapr_vio_busdev_init; + info->bus_info = &spapr_vio_bus_info; - assert(info->qdev.size >= sizeof(VIOsPAPRDevice)); - qdev_register(&info->qdev); + assert(info->size >= sizeof(VIOsPAPRDevice)); + qdev_register_subclass(info, TYPE_VIO_SPAPR_DEVICE); } static target_ulong h_vio_signal(CPUState *env, sPAPREnvironment *spapr, @@ -694,15 +696,15 @@ static target_ulong h_vio_signal(CPUState *env, sPAPREnvironment *spapr, target_ulong reg = args[0]; target_ulong mode = args[1]; VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg); - VIOsPAPRDeviceInfo *info; + VIOsPAPRDeviceClass *pc; if (!dev) { return H_PARAMETER; } - info = (VIOsPAPRDeviceInfo *)qdev_get_info(&dev->qdev); + pc = VIO_SPAPR_DEVICE_GET_CLASS(dev); - if (mode & ~info->signal_mask) { + if (mode & ~pc->signal_mask) { return H_PARAMETER; } @@ -760,9 +762,18 @@ static SysBusDeviceInfo spapr_vio_bridge_info = { .qdev.no_user = 1, }; +static TypeInfo spapr_vio_type_info = { + .name = TYPE_VIO_SPAPR_DEVICE, + .parent = TYPE_DEVICE, + .instance_size = sizeof(VIOsPAPRDevice), + .abstract = true, + .class_size = sizeof(VIOsPAPRDeviceClass), +}; + static void spapr_vio_register_devices(void) { sysbus_register_withprop(&spapr_vio_bridge_info); + type_register_static(&spapr_vio_type_info); } device_init(spapr_vio_register_devices) diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h index 0984d559db..7d1155a060 100644 --- a/hw/spapr_vio.h +++ b/hw/spapr_vio.h @@ -34,6 +34,14 @@ enum VIOsPAPR_TCEAccess { #define SPAPR_VTY_BASE_ADDRESS 0x30000000 +#define TYPE_VIO_SPAPR_DEVICE "vio-spapr-device" +#define VIO_SPAPR_DEVICE(obj) \ + OBJECT_CHECK(VIOsPAPRDevice, (obj), TYPE_VIO_SPAPR_DEVICE) +#define VIO_SPAPR_DEVICE_CLASS(klass) \ + OBJECT_CLASS_CHECK(VIOsPAPRDeviceClass, (klass), TYPE_VIO_SPAPR_DEVICE) +#define VIO_SPAPR_DEVICE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VIOsPAPRDeviceClass, (obj), TYPE_VIO_SPAPR_DEVICE) + struct VIOsPAPRDevice; typedef struct VIOsPAPR_RTCE { @@ -47,7 +55,20 @@ typedef struct VIOsPAPR_CRQ { int(*SendFunc)(struct VIOsPAPRDevice *vdev, uint8_t *crq); } VIOsPAPR_CRQ; -typedef struct VIOsPAPRDevice { +typedef struct VIOsPAPRDevice VIOsPAPRDevice; +typedef struct VIOsPAPRBus VIOsPAPRBus; + +typedef struct VIOsPAPRDeviceClass { + DeviceClass parent_class; + + const char *dt_name, *dt_type, *dt_compatible; + target_ulong signal_mask; + int (*init)(VIOsPAPRDevice *dev); + void (*hcalls)(VIOsPAPRBus *bus); + int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off); +} VIOsPAPRDeviceClass; + +struct VIOsPAPRDevice { DeviceState qdev; uint32_t reg; uint32_t flags; @@ -59,28 +80,24 @@ typedef struct VIOsPAPRDevice { VIOsPAPR_RTCE *rtce_table; int kvmtce_fd; VIOsPAPR_CRQ crq; -} VIOsPAPRDevice; +}; #define DEFINE_SPAPR_PROPERTIES(type, field, default_reg, default_dma_window) \ DEFINE_PROP_UINT32("reg", type, field.reg, default_reg), \ DEFINE_PROP_UINT32("dma-window", type, field.rtce_window_size, \ default_dma_window) -typedef struct VIOsPAPRBus { +struct VIOsPAPRBus { BusState bus; -} VIOsPAPRBus; - -typedef struct { - DeviceInfo qdev; const char *dt_name, *dt_type, *dt_compatible; target_ulong signal_mask; int (*init)(VIOsPAPRDevice *dev); int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off); -} VIOsPAPRDeviceInfo; +}; extern VIOsPAPRBus *spapr_vio_bus_init(void); extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg); -extern void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info); +extern void spapr_vio_bus_register_withprop(DeviceInfo *info); extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt); extern int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus); diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c index 21d946e2c5..b83bb7f341 100644 --- a/hw/spapr_vscsi.c +++ b/hw/spapr_vscsi.c @@ -947,19 +947,28 @@ static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off) return 0; } -static VIOsPAPRDeviceInfo spapr_vscsi_info = { - .init = spapr_vscsi_init, - .devnode = spapr_vscsi_devnode, - .dt_name = "v-scsi", - .dt_type = "vscsi", - .dt_compatible = "IBM,v-scsi", - .signal_mask = 0x00000001, - .qdev.name = "spapr-vscsi", - .qdev.size = sizeof(VSCSIState), - .qdev.props = (Property[]) { - DEFINE_SPAPR_PROPERTIES(VSCSIState, vdev, 0x2000, 0x10000000), - DEFINE_PROP_END_OF_LIST(), - }, +static Property spapr_vscsi_properties[] = { + DEFINE_SPAPR_PROPERTIES(VSCSIState, vdev, 0x2000, 0x10000000), + DEFINE_PROP_END_OF_LIST(), +}; + +static void spapr_vscsi_class_init(ObjectClass *klass, void *data) +{ + VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass); + + k->init = spapr_vscsi_init; + k->devnode = spapr_vscsi_devnode; + k->dt_name = "v-scsi"; + k->dt_type = "vscsi"; + k->dt_compatible = "IBM,v-scsi"; + k->signal_mask = 0x00000001; +} + +static DeviceInfo spapr_vscsi_info = { + .name = "spapr-vscsi", + .size = sizeof(VSCSIState), + .props = spapr_vscsi_properties, + .class_init = spapr_vscsi_class_init, }; static void spapr_vscsi_register(void) diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c index 3d5c579311..1780ffea32 100644 --- a/hw/spapr_vty.c +++ b/hw/spapr_vty.c @@ -135,18 +135,27 @@ void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, CharDriverState *chardev) qdev_init_nofail(dev); } -static VIOsPAPRDeviceInfo spapr_vty_info = { - .init = spapr_vty_init, - .dt_name = "vty", - .dt_type = "serial", - .dt_compatible = "hvterm1", - .qdev.name = "spapr-vty", - .qdev.size = sizeof(VIOsPAPRVTYDevice), - .qdev.props = (Property[]) { - DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, SPAPR_VTY_BASE_ADDRESS, 0), - DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev), - DEFINE_PROP_END_OF_LIST(), - }, +static Property spapr_vty_properties[] = { + DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, SPAPR_VTY_BASE_ADDRESS, 0), + DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev), + DEFINE_PROP_END_OF_LIST(), +}; + +static void spapr_vty_class_init(ObjectClass *klass, void *data) +{ + VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass); + + k->init = spapr_vty_init; + k->dt_name = "vty"; + k->dt_type = "serial"; + k->dt_compatible = "hvterm1"; +} + +static DeviceInfo spapr_vty_info = { + .name = "spapr-vty", + .size = sizeof(VIOsPAPRVTYDevice), + .props = spapr_vty_properties, + .class_init = spapr_vty_class_init, }; VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus) @@ -163,7 +172,7 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus) selected = NULL; QTAILQ_FOREACH(iter, &bus->bus.children, sibling) { /* Only look at VTY devices */ - if (qdev_get_info(iter) != &spapr_vty_info.qdev) { + if (!object_dynamic_cast(OBJECT(iter), "spapr-vty")) { continue; } |