]> Git Repo - qemu.git/blob - hw/s390x/s390-virtio-bus.c
PPC: Fix dma interrupt
[qemu.git] / hw / s390x / s390-virtio-bus.c
1 /*
2  * QEMU S390 virtio target
3  *
4  * Copyright (c) 2009 Alexander Graf <[email protected]>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "hw/hw.h"
21 #include "block/block.h"
22 #include "sysemu/sysemu.h"
23 #include "hw/boards.h"
24 #include "monitor/monitor.h"
25 #include "hw/loader.h"
26 #include "elf.h"
27 #include "hw/virtio.h"
28 #include "hw/virtio-rng.h"
29 #include "hw/virtio-serial.h"
30 #include "hw/virtio-net.h"
31 #include "hw/sysbus.h"
32 #include "sysemu/kvm.h"
33
34 #include "hw/s390x/s390-virtio-bus.h"
35 #include "hw/virtio-bus.h"
36
37 /* #define DEBUG_S390 */
38
39 #ifdef DEBUG_S390
40 #define dprintf(fmt, ...) \
41     do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
42 #else
43 #define dprintf(fmt, ...) \
44     do { } while (0)
45 #endif
46
47 #define VIRTIO_EXT_CODE   0x2603
48
49 static const TypeInfo s390_virtio_bus_info = {
50     .name = TYPE_S390_VIRTIO_BUS,
51     .parent = TYPE_BUS,
52     .instance_size = sizeof(VirtIOS390Bus),
53 };
54
55 static const VirtIOBindings virtio_s390_bindings;
56
57 static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
58
59 /* length of VirtIO device pages */
60 const hwaddr virtio_size = S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
61
62 static void s390_virtio_bus_reset(void *opaque)
63 {
64     VirtIOS390Bus *bus = opaque;
65     bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
66 }
67
68 void s390_virtio_reset_idx(VirtIOS390Device *dev)
69 {
70     int i;
71     hwaddr idx_addr;
72     uint8_t num_vq;
73
74     num_vq = s390_virtio_device_num_vq(dev);
75     for (i = 0; i < num_vq; i++) {
76         idx_addr = virtio_queue_get_avail_addr(dev->vdev, i) +
77             VIRTIO_VRING_AVAIL_IDX_OFFS;
78         stw_phys(idx_addr, 0);
79         idx_addr = virtio_queue_get_used_addr(dev->vdev, i) +
80             VIRTIO_VRING_USED_IDX_OFFS;
81         stw_phys(idx_addr, 0);
82     }
83 }
84
85 VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
86 {
87     VirtIOS390Bus *bus;
88     BusState *_bus;
89     DeviceState *dev;
90
91     /* Create bridge device */
92     dev = qdev_create(NULL, "s390-virtio-bridge");
93     qdev_init_nofail(dev);
94
95     /* Create bus on bridge device */
96
97     _bus = qbus_create(TYPE_S390_VIRTIO_BUS, dev, "s390-virtio");
98     bus = DO_UPCAST(VirtIOS390Bus, bus, _bus);
99
100     bus->dev_page = *ram_size;
101     bus->dev_offs = bus->dev_page;
102     bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
103
104     /* Enable hotplugging */
105     _bus->allow_hotplug = 1;
106
107     /* Allocate RAM for VirtIO device pages (descriptors, queues, rings) */
108     *ram_size += S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
109
110     qemu_register_reset(s390_virtio_bus_reset, bus);
111     return bus;
112 }
113
114 static void s390_virtio_irq(S390CPU *cpu, int config_change, uint64_t token)
115 {
116     if (kvm_enabled()) {
117         kvm_s390_virtio_irq(cpu, config_change, token);
118     } else {
119         cpu_inject_ext(cpu, VIRTIO_EXT_CODE, config_change, token);
120     }
121 }
122
123 static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
124 {
125     VirtIOS390Bus *bus;
126     int dev_len;
127
128     bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
129     dev->vdev = vdev;
130     dev->dev_offs = bus->dev_offs;
131     dev->feat_len = sizeof(uint32_t); /* always keep 32 bits features */
132
133     dev_len = VIRTIO_DEV_OFFS_CONFIG;
134     dev_len += s390_virtio_device_num_vq(dev) * VIRTIO_VQCONFIG_LEN;
135     dev_len += dev->feat_len * 2;
136     dev_len += vdev->config_len;
137
138     bus->dev_offs += dev_len;
139
140     virtio_bind_device(vdev, &virtio_s390_bindings, DEVICE(dev));
141     dev->host_features = vdev->get_features(vdev, dev->host_features);
142     s390_virtio_device_sync(dev);
143     s390_virtio_reset_idx(dev);
144     if (dev->qdev.hotplugged) {
145         S390CPU *cpu = s390_cpu_addr2state(0);
146         s390_virtio_irq(cpu, VIRTIO_PARAM_DEV_ADD, dev->dev_offs);
147     }
148
149     return 0;
150 }
151
152 static int s390_virtio_net_init(VirtIOS390Device *dev)
153 {
154     VirtIODevice *vdev;
155
156     vdev = virtio_net_init((DeviceState *)dev, &dev->nic, &dev->net,
157                            dev->host_features);
158     if (!vdev) {
159         return -1;
160     }
161
162     return s390_virtio_device_init(dev, vdev);
163 }
164
165 static int s390_virtio_blk_init(VirtIOS390Device *dev)
166 {
167     VirtIODevice *vdev;
168
169     vdev = virtio_blk_init((DeviceState *)dev, &dev->blk);
170     if (!vdev) {
171         return -1;
172     }
173
174     return s390_virtio_device_init(dev, vdev);
175 }
176
177 static int s390_virtio_serial_init(VirtIOS390Device *dev)
178 {
179     VirtIOS390Bus *bus;
180     VirtIODevice *vdev;
181     int r;
182
183     bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
184
185     vdev = virtio_serial_init((DeviceState *)dev, &dev->serial);
186     if (!vdev) {
187         return -1;
188     }
189
190     r = s390_virtio_device_init(dev, vdev);
191     if (!r) {
192         bus->console = dev;
193     }
194
195     return r;
196 }
197
198 static int s390_virtio_scsi_init(VirtIOS390Device *dev)
199 {
200     VirtIODevice *vdev;
201
202     vdev = virtio_scsi_init((DeviceState *)dev, &dev->scsi);
203     if (!vdev) {
204         return -1;
205     }
206
207     return s390_virtio_device_init(dev, vdev);
208 }
209
210 static int s390_virtio_rng_init(VirtIOS390Device *dev)
211 {
212     VirtIODevice *vdev;
213
214     vdev = virtio_rng_init((DeviceState *)dev, &dev->rng);
215     if (!vdev) {
216         return -1;
217     }
218
219     return s390_virtio_device_init(dev, vdev);
220 }
221
222 static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
223 {
224     ram_addr_t token_off;
225
226     token_off = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
227                 (vq * VIRTIO_VQCONFIG_LEN) +
228                 VIRTIO_VQCONFIG_OFFS_TOKEN;
229
230     return ldq_be_phys(token_off);
231 }
232
233 static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev)
234 {
235     VirtIODevice *vdev = dev->vdev;
236     int num_vq;
237
238     for (num_vq = 0; num_vq < VIRTIO_PCI_QUEUE_MAX; num_vq++) {
239         if (!virtio_queue_get_num(vdev, num_vq)) {
240             break;
241         }
242     }
243
244     return num_vq;
245 }
246
247 static ram_addr_t s390_virtio_next_ring(VirtIOS390Bus *bus)
248 {
249     ram_addr_t r = bus->next_ring;
250
251     bus->next_ring += VIRTIO_RING_LEN;
252     return r;
253 }
254
255 void s390_virtio_device_sync(VirtIOS390Device *dev)
256 {
257     VirtIOS390Bus *bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
258     ram_addr_t cur_offs;
259     uint8_t num_vq;
260     int i;
261
262     virtio_reset(dev->vdev);
263
264     /* Sync dev space */
265     stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_TYPE, dev->vdev->device_id);
266
267     stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, s390_virtio_device_num_vq(dev));
268     stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_FEATURE_LEN, dev->feat_len);
269
270     stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG_LEN, dev->vdev->config_len);
271
272     num_vq = s390_virtio_device_num_vq(dev);
273     stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, num_vq);
274
275     /* Sync virtqueues */
276     for (i = 0; i < num_vq; i++) {
277         ram_addr_t vq = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
278                         (i * VIRTIO_VQCONFIG_LEN);
279         ram_addr_t vring;
280
281         vring = s390_virtio_next_ring(bus);
282         virtio_queue_set_addr(dev->vdev, i, vring);
283         virtio_queue_set_vector(dev->vdev, i, i);
284         stq_be_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
285         stw_be_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i));
286     }
287
288     cur_offs = dev->dev_offs;
289     cur_offs += VIRTIO_DEV_OFFS_CONFIG;
290     cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
291
292     /* Sync feature bitmap */
293     stl_le_phys(cur_offs, dev->host_features);
294
295     dev->feat_offs = cur_offs + dev->feat_len;
296     cur_offs += dev->feat_len * 2;
297
298     /* Sync config space */
299     if (dev->vdev->get_config) {
300         dev->vdev->get_config(dev->vdev, dev->vdev->config);
301     }
302
303     cpu_physical_memory_write(cur_offs,
304                               dev->vdev->config, dev->vdev->config_len);
305     cur_offs += dev->vdev->config_len;
306 }
307
308 void s390_virtio_device_update_status(VirtIOS390Device *dev)
309 {
310     VirtIODevice *vdev = dev->vdev;
311     uint32_t features;
312
313     virtio_set_status(vdev, ldub_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS));
314
315     /* Update guest supported feature bitmap */
316
317     features = bswap32(ldl_be_phys(dev->feat_offs));
318     virtio_set_features(vdev, features);
319 }
320
321 VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus)
322 {
323     return bus->console;
324 }
325
326 /* Find a device by vring address */
327 VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
328                                              ram_addr_t mem,
329                                              int *vq_num)
330 {
331     BusChild *kid;
332     int i;
333
334     QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
335         VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
336
337         for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
338             if (!virtio_queue_get_addr(dev->vdev, i))
339                 break;
340             if (virtio_queue_get_addr(dev->vdev, i) == mem) {
341                 if (vq_num) {
342                     *vq_num = i;
343                 }
344                 return dev;
345             }
346         }
347     }
348
349     return NULL;
350 }
351
352 /* Find a device by device descriptor location */
353 VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)
354 {
355     BusChild *kid;
356
357     QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
358         VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
359         if (dev->dev_offs == mem) {
360             return dev;
361         }
362     }
363
364     return NULL;
365 }
366
367 /* DeviceState to VirtIOS390Device. Note: used on datapath,
368  * be careful and test performance if you change this.
369  */
370 static inline VirtIOS390Device *to_virtio_s390_device_fast(DeviceState *d)
371 {
372     return container_of(d, VirtIOS390Device, qdev);
373 }
374
375 /* DeviceState to VirtIOS390Device. TODO: use QOM. */
376 static inline VirtIOS390Device *to_virtio_s390_device(DeviceState *d)
377 {
378     return container_of(d, VirtIOS390Device, qdev);
379 }
380
381 static void virtio_s390_notify(DeviceState *d, uint16_t vector)
382 {
383     VirtIOS390Device *dev = to_virtio_s390_device_fast(d);
384     uint64_t token = s390_virtio_device_vq_token(dev, vector);
385     S390CPU *cpu = s390_cpu_addr2state(0);
386
387     s390_virtio_irq(cpu, 0, token);
388 }
389
390 static unsigned virtio_s390_get_features(DeviceState *d)
391 {
392     VirtIOS390Device *dev = to_virtio_s390_device(d);
393     return dev->host_features;
394 }
395
396 /**************** S390 Virtio Bus Device Descriptions *******************/
397
398 static const VirtIOBindings virtio_s390_bindings = {
399     .notify = virtio_s390_notify,
400     .get_features = virtio_s390_get_features,
401 };
402
403 static Property s390_virtio_net_properties[] = {
404     DEFINE_NIC_PROPERTIES(VirtIOS390Device, nic),
405     DEFINE_PROP_UINT32("x-txtimer", VirtIOS390Device,
406                        net.txtimer, TX_TIMER_INTERVAL),
407     DEFINE_PROP_INT32("x-txburst", VirtIOS390Device,
408                       net.txburst, TX_BURST),
409     DEFINE_PROP_STRING("tx", VirtIOS390Device, net.tx),
410     DEFINE_PROP_END_OF_LIST(),
411 };
412
413 static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
414 {
415     DeviceClass *dc = DEVICE_CLASS(klass);
416     VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
417
418     k->init = s390_virtio_net_init;
419     dc->props = s390_virtio_net_properties;
420 }
421
422 static const TypeInfo s390_virtio_net = {
423     .name          = "virtio-net-s390",
424     .parent        = TYPE_VIRTIO_S390_DEVICE,
425     .instance_size = sizeof(VirtIOS390Device),
426     .class_init    = s390_virtio_net_class_init,
427 };
428
429 static Property s390_virtio_blk_properties[] = {
430     DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, blk.conf),
431     DEFINE_BLOCK_CHS_PROPERTIES(VirtIOS390Device, blk.conf),
432     DEFINE_PROP_STRING("serial", VirtIOS390Device, blk.serial),
433 #ifdef __linux__
434     DEFINE_PROP_BIT("scsi", VirtIOS390Device, blk.scsi, 0, true),
435 #endif
436     DEFINE_PROP_END_OF_LIST(),
437 };
438
439 static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
440 {
441     DeviceClass *dc = DEVICE_CLASS(klass);
442     VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
443
444     k->init = s390_virtio_blk_init;
445     dc->props = s390_virtio_blk_properties;
446 }
447
448 static const TypeInfo s390_virtio_blk = {
449     .name          = "virtio-blk-s390",
450     .parent        = TYPE_VIRTIO_S390_DEVICE,
451     .instance_size = sizeof(VirtIOS390Device),
452     .class_init    = s390_virtio_blk_class_init,
453 };
454
455 static Property s390_virtio_serial_properties[] = {
456     DEFINE_PROP_UINT32("max_ports", VirtIOS390Device,
457                        serial.max_virtserial_ports, 31),
458     DEFINE_PROP_END_OF_LIST(),
459 };
460
461 static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
462 {
463     DeviceClass *dc = DEVICE_CLASS(klass);
464     VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
465
466     k->init = s390_virtio_serial_init;
467     dc->props = s390_virtio_serial_properties;
468 }
469
470 static const TypeInfo s390_virtio_serial = {
471     .name          = "virtio-serial-s390",
472     .parent        = TYPE_VIRTIO_S390_DEVICE,
473     .instance_size = sizeof(VirtIOS390Device),
474     .class_init    = s390_virtio_serial_class_init,
475 };
476
477 static void s390_virtio_rng_initfn(Object *obj)
478 {
479     VirtIOS390Device *dev = VIRTIO_S390_DEVICE(obj);
480
481     object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
482                              (Object **)&dev->rng.rng, NULL);
483 }
484
485 static void s390_virtio_rng_class_init(ObjectClass *klass, void *data)
486 {
487     VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
488
489     k->init = s390_virtio_rng_init;
490 }
491
492 static const TypeInfo s390_virtio_rng = {
493     .name          = "virtio-rng-s390",
494     .parent        = TYPE_VIRTIO_S390_DEVICE,
495     .instance_size = sizeof(VirtIOS390Device),
496     .instance_init = s390_virtio_rng_initfn,
497     .class_init    = s390_virtio_rng_class_init,
498 };
499
500 static int s390_virtio_busdev_init(DeviceState *dev)
501 {
502     VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
503     VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev);
504
505     virtio_s390_bus_new(&_dev->bus, _dev);
506
507     return _info->init(_dev);
508 }
509
510 static void s390_virtio_busdev_reset(DeviceState *dev)
511 {
512     VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
513
514     virtio_reset(_dev->vdev);
515 }
516
517 static void virtio_s390_device_class_init(ObjectClass *klass, void *data)
518 {
519     DeviceClass *dc = DEVICE_CLASS(klass);
520
521     dc->init = s390_virtio_busdev_init;
522     dc->bus_type = TYPE_S390_VIRTIO_BUS;
523     dc->unplug = qdev_simple_unplug_cb;
524     dc->reset = s390_virtio_busdev_reset;
525 }
526
527 static const TypeInfo virtio_s390_device_info = {
528     .name = TYPE_VIRTIO_S390_DEVICE,
529     .parent = TYPE_DEVICE,
530     .instance_size = sizeof(VirtIOS390Device),
531     .class_init = virtio_s390_device_class_init,
532     .class_size = sizeof(VirtIOS390DeviceClass),
533     .abstract = true,
534 };
535
536 static Property s390_virtio_scsi_properties[] = {
537     DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOS390Device, host_features, scsi),
538     DEFINE_PROP_END_OF_LIST(),
539 };
540
541 static void s390_virtio_scsi_class_init(ObjectClass *klass, void *data)
542 {
543     DeviceClass *dc = DEVICE_CLASS(klass);
544     VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
545
546     k->init = s390_virtio_scsi_init;
547     dc->props = s390_virtio_scsi_properties;
548 }
549
550 static const TypeInfo s390_virtio_scsi = {
551     .name          = "virtio-scsi-s390",
552     .parent        = TYPE_VIRTIO_S390_DEVICE,
553     .instance_size = sizeof(VirtIOS390Device),
554     .class_init    = s390_virtio_scsi_class_init,
555 };
556
557 /***************** S390 Virtio Bus Bridge Device *******************/
558 /* Only required to have the virtio bus as child in the system bus */
559
560 static int s390_virtio_bridge_init(SysBusDevice *dev)
561 {
562     /* nothing */
563     return 0;
564 }
565
566 static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data)
567 {
568     DeviceClass *dc = DEVICE_CLASS(klass);
569     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
570
571     k->init = s390_virtio_bridge_init;
572     dc->no_user = 1;
573 }
574
575 static const TypeInfo s390_virtio_bridge_info = {
576     .name          = "s390-virtio-bridge",
577     .parent        = TYPE_SYS_BUS_DEVICE,
578     .instance_size = sizeof(SysBusDevice),
579     .class_init    = s390_virtio_bridge_class_init,
580 };
581
582 /* virtio-s390-bus */
583
584 void virtio_s390_bus_new(VirtioBusState *bus, VirtIOS390Device *dev)
585 {
586     DeviceState *qdev = DEVICE(dev);
587     BusState *qbus;
588     qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_S390_BUS, qdev, NULL);
589     qbus = BUS(bus);
590     qbus->allow_hotplug = 0;
591 }
592
593 static void virtio_s390_bus_class_init(ObjectClass *klass, void *data)
594 {
595     VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
596     BusClass *bus_class = BUS_CLASS(klass);
597     bus_class->max_dev = 1;
598     k->notify = virtio_s390_notify;
599     k->get_features = virtio_s390_get_features;
600 }
601
602 static const TypeInfo virtio_s390_bus_info = {
603     .name          = TYPE_VIRTIO_S390_BUS,
604     .parent        = TYPE_VIRTIO_BUS,
605     .instance_size = sizeof(VirtioS390BusState),
606     .class_init    = virtio_s390_bus_class_init,
607 };
608
609 static void s390_virtio_register_types(void)
610 {
611     type_register_static(&virtio_s390_bus_info);
612     type_register_static(&s390_virtio_bus_info);
613     type_register_static(&virtio_s390_device_info);
614     type_register_static(&s390_virtio_serial);
615     type_register_static(&s390_virtio_blk);
616     type_register_static(&s390_virtio_net);
617     type_register_static(&s390_virtio_scsi);
618     type_register_static(&s390_virtio_rng);
619     type_register_static(&s390_virtio_bridge_info);
620 }
621
622 type_init(s390_virtio_register_types)
This page took 0.058949 seconds and 4 git commands to generate.