aboutsummaryrefslogtreecommitdiff
path: root/hw/s390-virtio-bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/s390-virtio-bus.c')
-rw-r--r--hw/s390-virtio-bus.c86
1 files changed, 68 insertions, 18 deletions
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index a245684692..7e991755b4 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -18,18 +18,18 @@
*/
#include "hw.h"
-#include "block.h"
-#include "sysemu.h"
-#include "net.h"
+#include "block/block.h"
+#include "sysemu/sysemu.h"
#include "boards.h"
-#include "monitor.h"
+#include "monitor/monitor.h"
#include "loader.h"
#include "elf.h"
#include "hw/virtio.h"
+#include "hw/virtio-rng.h"
#include "hw/virtio-serial.h"
#include "hw/virtio-net.h"
#include "hw/sysbus.h"
-#include "kvm.h"
+#include "sysemu/kvm.h"
#include "hw/s390-virtio-bus.h"
@@ -56,7 +56,7 @@ static const VirtIOBindings virtio_s390_bindings;
static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
/* length of VirtIO device pages */
-const target_phys_addr_t virtio_size = S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
+const hwaddr virtio_size = S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
static void s390_virtio_bus_reset(void *opaque)
{
@@ -67,7 +67,7 @@ static void s390_virtio_bus_reset(void *opaque)
void s390_virtio_reset_idx(VirtIOS390Device *dev)
{
int i;
- target_phys_addr_t idx_addr;
+ hwaddr idx_addr;
uint8_t num_vq;
num_vq = s390_virtio_device_num_vq(dev);
@@ -110,10 +110,12 @@ VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
return bus;
}
-static void s390_virtio_irq(CPUS390XState *env, int config_change, uint64_t token)
+static void s390_virtio_irq(S390CPU *cpu, int config_change, uint64_t token)
{
+ CPUS390XState *env = &cpu->env;
+
if (kvm_enabled()) {
- kvm_s390_virtio_irq(env, config_change, token);
+ kvm_s390_virtio_irq(cpu, config_change, token);
} else {
cpu_inject_ext(env, VIRTIO_EXT_CODE, config_change, token);
}
@@ -136,14 +138,13 @@ static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
bus->dev_offs += dev_len;
- virtio_bind_device(vdev, &virtio_s390_bindings, dev);
+ virtio_bind_device(vdev, &virtio_s390_bindings, DEVICE(dev));
dev->host_features = vdev->get_features(vdev, dev->host_features);
s390_virtio_device_sync(dev);
s390_virtio_reset_idx(dev);
if (dev->qdev.hotplugged) {
S390CPU *cpu = s390_cpu_addr2state(0);
- CPUS390XState *env = &cpu->env;
- s390_virtio_irq(env, VIRTIO_PARAM_DEV_ADD, dev->dev_offs);
+ s390_virtio_irq(cpu, VIRTIO_PARAM_DEV_ADD, dev->dev_offs);
}
return 0;
@@ -206,6 +207,18 @@ static int s390_virtio_scsi_init(VirtIOS390Device *dev)
return s390_virtio_device_init(dev, vdev);
}
+static int s390_virtio_rng_init(VirtIOS390Device *dev)
+{
+ VirtIODevice *vdev;
+
+ vdev = virtio_rng_init((DeviceState *)dev, &dev->rng);
+ if (!vdev) {
+ return -1;
+ }
+
+ return s390_virtio_device_init(dev, vdev);
+}
+
static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
{
ram_addr_t token_off;
@@ -351,19 +364,32 @@ VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)
return NULL;
}
-static void virtio_s390_notify(void *opaque, uint16_t vector)
+/* DeviceState to VirtIOS390Device. Note: used on datapath,
+ * be careful and test performance if you change this.
+ */
+static inline VirtIOS390Device *to_virtio_s390_device_fast(DeviceState *d)
+{
+ return container_of(d, VirtIOS390Device, qdev);
+}
+
+/* DeviceState to VirtIOS390Device. TODO: use QOM. */
+static inline VirtIOS390Device *to_virtio_s390_device(DeviceState *d)
{
- VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
+ return container_of(d, VirtIOS390Device, qdev);
+}
+
+static void virtio_s390_notify(DeviceState *d, uint16_t vector)
+{
+ VirtIOS390Device *dev = to_virtio_s390_device_fast(d);
uint64_t token = s390_virtio_device_vq_token(dev, vector);
S390CPU *cpu = s390_cpu_addr2state(0);
- CPUS390XState *env = &cpu->env;
- s390_virtio_irq(env, 0, token);
+ s390_virtio_irq(cpu, 0, token);
}
-static unsigned virtio_s390_get_features(void *opaque)
+static unsigned virtio_s390_get_features(DeviceState *d)
{
- VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
+ VirtIOS390Device *dev = to_virtio_s390_device(d);
return dev->host_features;
}
@@ -448,6 +474,29 @@ static TypeInfo s390_virtio_serial = {
.class_init = s390_virtio_serial_class_init,
};
+static void s390_virtio_rng_initfn(Object *obj)
+{
+ VirtIOS390Device *dev = VIRTIO_S390_DEVICE(obj);
+
+ object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
+ (Object **)&dev->rng.rng, NULL);
+}
+
+static void s390_virtio_rng_class_init(ObjectClass *klass, void *data)
+{
+ VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
+
+ k->init = s390_virtio_rng_init;
+}
+
+static TypeInfo s390_virtio_rng = {
+ .name = "virtio-rng-s390",
+ .parent = TYPE_VIRTIO_S390_DEVICE,
+ .instance_size = sizeof(VirtIOS390Device),
+ .instance_init = s390_virtio_rng_initfn,
+ .class_init = s390_virtio_rng_class_init,
+};
+
static int s390_virtio_busdev_init(DeviceState *dev)
{
VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
@@ -528,6 +577,7 @@ static void s390_virtio_register_types(void)
type_register_static(&s390_virtio_blk);
type_register_static(&s390_virtio_net);
type_register_static(&s390_virtio_scsi);
+ type_register_static(&s390_virtio_rng);
type_register_static(&s390_virtio_bridge_info);
}