mirror of https://github.com/xemu-project/xemu.git
spapr: convert to QEMU Object Model (v2)
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> --- v1 -> v2 - use QOM to check for the default console
This commit is contained in:
parent
b9eea3e6a4
commit
3954d33ab7
|
@ -474,20 +474,29 @@ static target_ulong h_multicast_ctrl(CPUState *env, sPAPREnvironment *spapr,
|
||||||
return H_SUCCESS;
|
return H_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VIOsPAPRDeviceInfo spapr_vlan_info = {
|
static Property spapr_vlan_properties[] = {
|
||||||
.init = spapr_vlan_init,
|
DEFINE_SPAPR_PROPERTIES(VIOsPAPRVLANDevice, sdev, 0x1000, 0x10000000),
|
||||||
.devnode = spapr_vlan_devnode,
|
DEFINE_NIC_PROPERTIES(VIOsPAPRVLANDevice, nicconf),
|
||||||
.dt_name = "l-lan",
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
.dt_type = "network",
|
};
|
||||||
.dt_compatible = "IBM,l-lan",
|
|
||||||
.signal_mask = 0x1,
|
static void spapr_vlan_class_init(ObjectClass *klass, void *data)
|
||||||
.qdev.name = "spapr-vlan",
|
{
|
||||||
.qdev.size = sizeof(VIOsPAPRVLANDevice),
|
VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
|
||||||
.qdev.props = (Property[]) {
|
|
||||||
DEFINE_SPAPR_PROPERTIES(VIOsPAPRVLANDevice, sdev, 0x1000, 0x10000000),
|
k->init = spapr_vlan_init;
|
||||||
DEFINE_NIC_PROPERTIES(VIOsPAPRVLANDevice, nicconf),
|
k->devnode = spapr_vlan_devnode;
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
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)
|
static void spapr_vlan_register(void)
|
||||||
|
|
|
@ -75,11 +75,11 @@ VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
|
||||||
|
|
||||||
static char *vio_format_dev_name(VIOsPAPRDevice *dev)
|
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;
|
char *name;
|
||||||
|
|
||||||
/* Device tree style name device@reg */
|
/* 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ static char *vio_format_dev_name(VIOsPAPRDevice *dev)
|
||||||
static int vio_make_devnode(VIOsPAPRDevice *dev,
|
static int vio_make_devnode(VIOsPAPRDevice *dev,
|
||||||
void *fdt)
|
void *fdt)
|
||||||
{
|
{
|
||||||
VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qdev_get_info(&dev->qdev);
|
VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||||
int vdevice_off, node_off, ret;
|
int vdevice_off, node_off, ret;
|
||||||
char *dt_name;
|
char *dt_name;
|
||||||
|
|
||||||
|
@ -115,17 +115,17 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->dt_type) {
|
if (pc->dt_type) {
|
||||||
ret = fdt_setprop_string(fdt, node_off, "device_type",
|
ret = fdt_setprop_string(fdt, node_off, "device_type",
|
||||||
info->dt_type);
|
pc->dt_type);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->dt_compatible) {
|
if (pc->dt_compatible) {
|
||||||
ret = fdt_setprop_string(fdt, node_off, "compatible",
|
ret = fdt_setprop_string(fdt, node_off, "compatible",
|
||||||
info->dt_compatible);
|
pc->dt_compatible);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -163,8 +163,8 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->devnode) {
|
if (pc->devnode) {
|
||||||
ret = (info->devnode)(dev, fdt, node_off);
|
ret = (pc->devnode)(dev, fdt, node_off);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -621,7 +621,7 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token,
|
||||||
rtas_st(rets, 0, 0);
|
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;
|
VIOsPAPRDevice *other_sdev;
|
||||||
DeviceState *qdev;
|
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) {
|
if (other_sdev != sdev && other_sdev->reg == sdev->reg) {
|
||||||
fprintf(stderr, "vio: %s and %s devices conflict at address %#x\n",
|
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;
|
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)
|
static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
|
||||||
{
|
{
|
||||||
VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
|
|
||||||
VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
|
VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
|
||||||
|
VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||||
char *id;
|
char *id;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = spapr_vio_check_reg(dev, info);
|
ret = spapr_vio_check_reg(dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -675,16 +677,16 @@ static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
|
||||||
|
|
||||||
rtce_init(dev);
|
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->init = spapr_vio_busdev_init;
|
||||||
info->qdev.bus_info = &spapr_vio_bus_info;
|
info->bus_info = &spapr_vio_bus_info;
|
||||||
|
|
||||||
assert(info->qdev.size >= sizeof(VIOsPAPRDevice));
|
assert(info->size >= sizeof(VIOsPAPRDevice));
|
||||||
qdev_register(&info->qdev);
|
qdev_register_subclass(info, TYPE_VIO_SPAPR_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static target_ulong h_vio_signal(CPUState *env, sPAPREnvironment *spapr,
|
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 reg = args[0];
|
||||||
target_ulong mode = args[1];
|
target_ulong mode = args[1];
|
||||||
VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||||
VIOsPAPRDeviceInfo *info;
|
VIOsPAPRDeviceClass *pc;
|
||||||
|
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
return H_PARAMETER;
|
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;
|
return H_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -760,9 +762,18 @@ static SysBusDeviceInfo spapr_vio_bridge_info = {
|
||||||
.qdev.no_user = 1,
|
.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)
|
static void spapr_vio_register_devices(void)
|
||||||
{
|
{
|
||||||
sysbus_register_withprop(&spapr_vio_bridge_info);
|
sysbus_register_withprop(&spapr_vio_bridge_info);
|
||||||
|
type_register_static(&spapr_vio_type_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
device_init(spapr_vio_register_devices)
|
device_init(spapr_vio_register_devices)
|
||||||
|
|
|
@ -34,6 +34,14 @@ enum VIOsPAPR_TCEAccess {
|
||||||
|
|
||||||
#define SPAPR_VTY_BASE_ADDRESS 0x30000000
|
#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;
|
struct VIOsPAPRDevice;
|
||||||
|
|
||||||
typedef struct VIOsPAPR_RTCE {
|
typedef struct VIOsPAPR_RTCE {
|
||||||
|
@ -47,7 +55,20 @@ typedef struct VIOsPAPR_CRQ {
|
||||||
int(*SendFunc)(struct VIOsPAPRDevice *vdev, uint8_t *crq);
|
int(*SendFunc)(struct VIOsPAPRDevice *vdev, uint8_t *crq);
|
||||||
} VIOsPAPR_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;
|
DeviceState qdev;
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
@ -59,28 +80,24 @@ typedef struct VIOsPAPRDevice {
|
||||||
VIOsPAPR_RTCE *rtce_table;
|
VIOsPAPR_RTCE *rtce_table;
|
||||||
int kvmtce_fd;
|
int kvmtce_fd;
|
||||||
VIOsPAPR_CRQ crq;
|
VIOsPAPR_CRQ crq;
|
||||||
} VIOsPAPRDevice;
|
};
|
||||||
|
|
||||||
#define DEFINE_SPAPR_PROPERTIES(type, field, default_reg, default_dma_window) \
|
#define DEFINE_SPAPR_PROPERTIES(type, field, default_reg, default_dma_window) \
|
||||||
DEFINE_PROP_UINT32("reg", type, field.reg, default_reg), \
|
DEFINE_PROP_UINT32("reg", type, field.reg, default_reg), \
|
||||||
DEFINE_PROP_UINT32("dma-window", type, field.rtce_window_size, \
|
DEFINE_PROP_UINT32("dma-window", type, field.rtce_window_size, \
|
||||||
default_dma_window)
|
default_dma_window)
|
||||||
|
|
||||||
typedef struct VIOsPAPRBus {
|
struct VIOsPAPRBus {
|
||||||
BusState bus;
|
BusState bus;
|
||||||
} VIOsPAPRBus;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
DeviceInfo qdev;
|
|
||||||
const char *dt_name, *dt_type, *dt_compatible;
|
const char *dt_name, *dt_type, *dt_compatible;
|
||||||
target_ulong signal_mask;
|
target_ulong signal_mask;
|
||||||
int (*init)(VIOsPAPRDevice *dev);
|
int (*init)(VIOsPAPRDevice *dev);
|
||||||
int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
|
int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
|
||||||
} VIOsPAPRDeviceInfo;
|
};
|
||||||
|
|
||||||
extern VIOsPAPRBus *spapr_vio_bus_init(void);
|
extern VIOsPAPRBus *spapr_vio_bus_init(void);
|
||||||
extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
|
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_vdevice(VIOsPAPRBus *bus, void *fdt);
|
||||||
extern int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus);
|
extern int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus);
|
||||||
|
|
||||||
|
|
|
@ -947,19 +947,28 @@ static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VIOsPAPRDeviceInfo spapr_vscsi_info = {
|
static Property spapr_vscsi_properties[] = {
|
||||||
.init = spapr_vscsi_init,
|
DEFINE_SPAPR_PROPERTIES(VSCSIState, vdev, 0x2000, 0x10000000),
|
||||||
.devnode = spapr_vscsi_devnode,
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
.dt_name = "v-scsi",
|
};
|
||||||
.dt_type = "vscsi",
|
|
||||||
.dt_compatible = "IBM,v-scsi",
|
static void spapr_vscsi_class_init(ObjectClass *klass, void *data)
|
||||||
.signal_mask = 0x00000001,
|
{
|
||||||
.qdev.name = "spapr-vscsi",
|
VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
|
||||||
.qdev.size = sizeof(VSCSIState),
|
|
||||||
.qdev.props = (Property[]) {
|
k->init = spapr_vscsi_init;
|
||||||
DEFINE_SPAPR_PROPERTIES(VSCSIState, vdev, 0x2000, 0x10000000),
|
k->devnode = spapr_vscsi_devnode;
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
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)
|
static void spapr_vscsi_register(void)
|
||||||
|
|
|
@ -135,18 +135,27 @@ void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, CharDriverState *chardev)
|
||||||
qdev_init_nofail(dev);
|
qdev_init_nofail(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VIOsPAPRDeviceInfo spapr_vty_info = {
|
static Property spapr_vty_properties[] = {
|
||||||
.init = spapr_vty_init,
|
DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, SPAPR_VTY_BASE_ADDRESS, 0),
|
||||||
.dt_name = "vty",
|
DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev),
|
||||||
.dt_type = "serial",
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
.dt_compatible = "hvterm1",
|
};
|
||||||
.qdev.name = "spapr-vty",
|
|
||||||
.qdev.size = sizeof(VIOsPAPRVTYDevice),
|
static void spapr_vty_class_init(ObjectClass *klass, void *data)
|
||||||
.qdev.props = (Property[]) {
|
{
|
||||||
DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, SPAPR_VTY_BASE_ADDRESS, 0),
|
VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
|
||||||
DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev),
|
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
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)
|
VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
|
||||||
|
@ -163,7 +172,7 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
|
||||||
selected = NULL;
|
selected = NULL;
|
||||||
QTAILQ_FOREACH(iter, &bus->bus.children, sibling) {
|
QTAILQ_FOREACH(iter, &bus->bus.children, sibling) {
|
||||||
/* Only look at VTY devices */
|
/* Only look at VTY devices */
|
||||||
if (qdev_get_info(iter) != &spapr_vty_info.qdev) {
|
if (!object_dynamic_cast(OBJECT(iter), "spapr-vty")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue