xref: /openbmc/qemu/hw/virtio/virtio-mmio.c (revision 8692aa29)
1 /*
2  * Virtio MMIO bindings
3  *
4  * Copyright (c) 2011 Linaro Limited
5  *
6  * Author:
7  *  Peter Maydell <peter.maydell@linaro.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "qemu/osdep.h"
23 #include "hw/sysbus.h"
24 #include "hw/virtio/virtio.h"
25 #include "qemu/host-utils.h"
26 #include "sysemu/kvm.h"
27 #include "hw/virtio/virtio-bus.h"
28 #include "qemu/error-report.h"
29 
30 /* #define DEBUG_VIRTIO_MMIO */
31 
32 #ifdef DEBUG_VIRTIO_MMIO
33 
34 #define DPRINTF(fmt, ...) \
35 do { printf("virtio_mmio: " fmt , ## __VA_ARGS__); } while (0)
36 #else
37 #define DPRINTF(fmt, ...) do {} while (0)
38 #endif
39 
40 /* QOM macros */
41 /* virtio-mmio-bus */
42 #define TYPE_VIRTIO_MMIO_BUS "virtio-mmio-bus"
43 #define VIRTIO_MMIO_BUS(obj) \
44         OBJECT_CHECK(VirtioBusState, (obj), TYPE_VIRTIO_MMIO_BUS)
45 #define VIRTIO_MMIO_BUS_GET_CLASS(obj) \
46         OBJECT_GET_CLASS(VirtioBusClass, (obj), TYPE_VIRTIO_MMIO_BUS)
47 #define VIRTIO_MMIO_BUS_CLASS(klass) \
48         OBJECT_CLASS_CHECK(VirtioBusClass, (klass), TYPE_VIRTIO_MMIO_BUS)
49 
50 /* virtio-mmio */
51 #define TYPE_VIRTIO_MMIO "virtio-mmio"
52 #define VIRTIO_MMIO(obj) \
53         OBJECT_CHECK(VirtIOMMIOProxy, (obj), TYPE_VIRTIO_MMIO)
54 
55 /* Memory mapped register offsets */
56 #define VIRTIO_MMIO_MAGIC 0x0
57 #define VIRTIO_MMIO_VERSION 0x4
58 #define VIRTIO_MMIO_DEVICEID 0x8
59 #define VIRTIO_MMIO_VENDORID 0xc
60 #define VIRTIO_MMIO_HOSTFEATURES 0x10
61 #define VIRTIO_MMIO_HOSTFEATURESSEL 0x14
62 #define VIRTIO_MMIO_GUESTFEATURES 0x20
63 #define VIRTIO_MMIO_GUESTFEATURESSEL 0x24
64 #define VIRTIO_MMIO_GUESTPAGESIZE 0x28
65 #define VIRTIO_MMIO_QUEUESEL 0x30
66 #define VIRTIO_MMIO_QUEUENUMMAX 0x34
67 #define VIRTIO_MMIO_QUEUENUM 0x38
68 #define VIRTIO_MMIO_QUEUEALIGN 0x3c
69 #define VIRTIO_MMIO_QUEUEPFN 0x40
70 #define VIRTIO_MMIO_QUEUENOTIFY 0x50
71 #define VIRTIO_MMIO_INTERRUPTSTATUS 0x60
72 #define VIRTIO_MMIO_INTERRUPTACK 0x64
73 #define VIRTIO_MMIO_STATUS 0x70
74 /* Device specific config space starts here */
75 #define VIRTIO_MMIO_CONFIG 0x100
76 
77 #define VIRT_MAGIC 0x74726976 /* 'virt' */
78 #define VIRT_VERSION 1
79 #define VIRT_VENDOR 0x554D4551 /* 'QEMU' */
80 
81 typedef struct {
82     /* Generic */
83     SysBusDevice parent_obj;
84     MemoryRegion iomem;
85     qemu_irq irq;
86     /* Guest accessible state needing migration and reset */
87     uint32_t host_features_sel;
88     uint32_t guest_features_sel;
89     uint32_t guest_page_shift;
90     /* virtio-bus */
91     VirtioBusState bus;
92     bool ioeventfd_disabled;
93     bool ioeventfd_started;
94 } VirtIOMMIOProxy;
95 
96 static bool virtio_mmio_ioeventfd_started(DeviceState *d)
97 {
98     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
99 
100     return proxy->ioeventfd_started;
101 }
102 
103 static void virtio_mmio_ioeventfd_set_started(DeviceState *d, bool started,
104                                               bool err)
105 {
106     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
107 
108     proxy->ioeventfd_started = started;
109 }
110 
111 static bool virtio_mmio_ioeventfd_disabled(DeviceState *d)
112 {
113     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
114 
115     return !kvm_eventfds_enabled() || proxy->ioeventfd_disabled;
116 }
117 
118 static void virtio_mmio_ioeventfd_set_disabled(DeviceState *d, bool disabled)
119 {
120     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
121 
122     proxy->ioeventfd_disabled = disabled;
123 }
124 
125 static int virtio_mmio_ioeventfd_assign(DeviceState *d,
126                                         EventNotifier *notifier,
127                                         int n, bool assign)
128 {
129     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
130 
131     if (assign) {
132         memory_region_add_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUENOTIFY, 4,
133                                   true, n, notifier);
134     } else {
135         memory_region_del_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUENOTIFY, 4,
136                                   true, n, notifier);
137     }
138     return 0;
139 }
140 
141 static void virtio_mmio_start_ioeventfd(VirtIOMMIOProxy *proxy)
142 {
143     virtio_bus_start_ioeventfd(&proxy->bus);
144 }
145 
146 static void virtio_mmio_stop_ioeventfd(VirtIOMMIOProxy *proxy)
147 {
148     virtio_bus_stop_ioeventfd(&proxy->bus);
149 }
150 
151 static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size)
152 {
153     VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque;
154     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
155 
156     DPRINTF("virtio_mmio_read offset 0x%x\n", (int)offset);
157 
158     if (!vdev) {
159         /* If no backend is present, we treat most registers as
160          * read-as-zero, except for the magic number, version and
161          * vendor ID. This is not strictly sanctioned by the virtio
162          * spec, but it allows us to provide transports with no backend
163          * plugged in which don't confuse Linux's virtio code: the
164          * probe won't complain about the bad magic number, but the
165          * device ID of zero means no backend will claim it.
166          */
167         switch (offset) {
168         case VIRTIO_MMIO_MAGIC:
169             return VIRT_MAGIC;
170         case VIRTIO_MMIO_VERSION:
171             return VIRT_VERSION;
172         case VIRTIO_MMIO_VENDORID:
173             return VIRT_VENDOR;
174         default:
175             return 0;
176         }
177     }
178 
179     if (offset >= VIRTIO_MMIO_CONFIG) {
180         offset -= VIRTIO_MMIO_CONFIG;
181         switch (size) {
182         case 1:
183             return virtio_config_readb(vdev, offset);
184         case 2:
185             return virtio_config_readw(vdev, offset);
186         case 4:
187             return virtio_config_readl(vdev, offset);
188         default:
189             abort();
190         }
191     }
192     if (size != 4) {
193         DPRINTF("wrong size access to register!\n");
194         return 0;
195     }
196     switch (offset) {
197     case VIRTIO_MMIO_MAGIC:
198         return VIRT_MAGIC;
199     case VIRTIO_MMIO_VERSION:
200         return VIRT_VERSION;
201     case VIRTIO_MMIO_DEVICEID:
202         return vdev->device_id;
203     case VIRTIO_MMIO_VENDORID:
204         return VIRT_VENDOR;
205     case VIRTIO_MMIO_HOSTFEATURES:
206         if (proxy->host_features_sel) {
207             return 0;
208         }
209         return vdev->host_features;
210     case VIRTIO_MMIO_QUEUENUMMAX:
211         if (!virtio_queue_get_num(vdev, vdev->queue_sel)) {
212             return 0;
213         }
214         return VIRTQUEUE_MAX_SIZE;
215     case VIRTIO_MMIO_QUEUEPFN:
216         return virtio_queue_get_addr(vdev, vdev->queue_sel)
217             >> proxy->guest_page_shift;
218     case VIRTIO_MMIO_INTERRUPTSTATUS:
219         return vdev->isr;
220     case VIRTIO_MMIO_STATUS:
221         return vdev->status;
222     case VIRTIO_MMIO_HOSTFEATURESSEL:
223     case VIRTIO_MMIO_GUESTFEATURES:
224     case VIRTIO_MMIO_GUESTFEATURESSEL:
225     case VIRTIO_MMIO_GUESTPAGESIZE:
226     case VIRTIO_MMIO_QUEUESEL:
227     case VIRTIO_MMIO_QUEUENUM:
228     case VIRTIO_MMIO_QUEUEALIGN:
229     case VIRTIO_MMIO_QUEUENOTIFY:
230     case VIRTIO_MMIO_INTERRUPTACK:
231         DPRINTF("read of write-only register\n");
232         return 0;
233     default:
234         DPRINTF("bad register offset\n");
235         return 0;
236     }
237     return 0;
238 }
239 
240 static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
241                               unsigned size)
242 {
243     VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque;
244     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
245 
246     DPRINTF("virtio_mmio_write offset 0x%x value 0x%" PRIx64 "\n",
247             (int)offset, value);
248 
249     if (!vdev) {
250         /* If no backend is present, we just make all registers
251          * write-ignored. This allows us to provide transports with
252          * no backend plugged in.
253          */
254         return;
255     }
256 
257     if (offset >= VIRTIO_MMIO_CONFIG) {
258         offset -= VIRTIO_MMIO_CONFIG;
259         switch (size) {
260         case 1:
261             virtio_config_writeb(vdev, offset, value);
262             break;
263         case 2:
264             virtio_config_writew(vdev, offset, value);
265             break;
266         case 4:
267             virtio_config_writel(vdev, offset, value);
268             break;
269         default:
270             abort();
271         }
272         return;
273     }
274     if (size != 4) {
275         DPRINTF("wrong size access to register!\n");
276         return;
277     }
278     switch (offset) {
279     case VIRTIO_MMIO_HOSTFEATURESSEL:
280         proxy->host_features_sel = value;
281         break;
282     case VIRTIO_MMIO_GUESTFEATURES:
283         if (!proxy->guest_features_sel) {
284             virtio_set_features(vdev, value);
285         }
286         break;
287     case VIRTIO_MMIO_GUESTFEATURESSEL:
288         proxy->guest_features_sel = value;
289         break;
290     case VIRTIO_MMIO_GUESTPAGESIZE:
291         proxy->guest_page_shift = ctz32(value);
292         if (proxy->guest_page_shift > 31) {
293             proxy->guest_page_shift = 0;
294         }
295         DPRINTF("guest page size %" PRIx64 " shift %d\n", value,
296                 proxy->guest_page_shift);
297         break;
298     case VIRTIO_MMIO_QUEUESEL:
299         if (value < VIRTIO_QUEUE_MAX) {
300             vdev->queue_sel = value;
301         }
302         break;
303     case VIRTIO_MMIO_QUEUENUM:
304         DPRINTF("mmio_queue write %d max %d\n", (int)value, VIRTQUEUE_MAX_SIZE);
305         virtio_queue_set_num(vdev, vdev->queue_sel, value);
306         /* Note: only call this function for legacy devices */
307         virtio_queue_update_rings(vdev, vdev->queue_sel);
308         break;
309     case VIRTIO_MMIO_QUEUEALIGN:
310         /* Note: this is only valid for legacy devices */
311         virtio_queue_set_align(vdev, vdev->queue_sel, value);
312         break;
313     case VIRTIO_MMIO_QUEUEPFN:
314         if (value == 0) {
315             virtio_reset(vdev);
316         } else {
317             virtio_queue_set_addr(vdev, vdev->queue_sel,
318                                   value << proxy->guest_page_shift);
319         }
320         break;
321     case VIRTIO_MMIO_QUEUENOTIFY:
322         if (value < VIRTIO_QUEUE_MAX) {
323             virtio_queue_notify(vdev, value);
324         }
325         break;
326     case VIRTIO_MMIO_INTERRUPTACK:
327         vdev->isr &= ~value;
328         virtio_update_irq(vdev);
329         break;
330     case VIRTIO_MMIO_STATUS:
331         if (!(value & VIRTIO_CONFIG_S_DRIVER_OK)) {
332             virtio_mmio_stop_ioeventfd(proxy);
333         }
334 
335         virtio_set_status(vdev, value & 0xff);
336 
337         if (value & VIRTIO_CONFIG_S_DRIVER_OK) {
338             virtio_mmio_start_ioeventfd(proxy);
339         }
340 
341         if (vdev->status == 0) {
342             virtio_reset(vdev);
343         }
344         break;
345     case VIRTIO_MMIO_MAGIC:
346     case VIRTIO_MMIO_VERSION:
347     case VIRTIO_MMIO_DEVICEID:
348     case VIRTIO_MMIO_VENDORID:
349     case VIRTIO_MMIO_HOSTFEATURES:
350     case VIRTIO_MMIO_QUEUENUMMAX:
351     case VIRTIO_MMIO_INTERRUPTSTATUS:
352         DPRINTF("write to readonly register\n");
353         break;
354 
355     default:
356         DPRINTF("bad register offset\n");
357     }
358 }
359 
360 static const MemoryRegionOps virtio_mem_ops = {
361     .read = virtio_mmio_read,
362     .write = virtio_mmio_write,
363     .endianness = DEVICE_NATIVE_ENDIAN,
364 };
365 
366 static void virtio_mmio_update_irq(DeviceState *opaque, uint16_t vector)
367 {
368     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
369     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
370     int level;
371 
372     if (!vdev) {
373         return;
374     }
375     level = (vdev->isr != 0);
376     DPRINTF("virtio_mmio setting IRQ %d\n", level);
377     qemu_set_irq(proxy->irq, level);
378 }
379 
380 static int virtio_mmio_load_config(DeviceState *opaque, QEMUFile *f)
381 {
382     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
383 
384     proxy->host_features_sel = qemu_get_be32(f);
385     proxy->guest_features_sel = qemu_get_be32(f);
386     proxy->guest_page_shift = qemu_get_be32(f);
387     return 0;
388 }
389 
390 static void virtio_mmio_save_config(DeviceState *opaque, QEMUFile *f)
391 {
392     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
393 
394     qemu_put_be32(f, proxy->host_features_sel);
395     qemu_put_be32(f, proxy->guest_features_sel);
396     qemu_put_be32(f, proxy->guest_page_shift);
397 }
398 
399 static void virtio_mmio_reset(DeviceState *d)
400 {
401     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
402 
403     virtio_mmio_stop_ioeventfd(proxy);
404     virtio_bus_reset(&proxy->bus);
405     proxy->host_features_sel = 0;
406     proxy->guest_features_sel = 0;
407     proxy->guest_page_shift = 0;
408 }
409 
410 static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign,
411                                           bool with_irqfd)
412 {
413     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
414     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
415     VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
416     VirtQueue *vq = virtio_get_queue(vdev, n);
417     EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
418 
419     if (assign) {
420         int r = event_notifier_init(notifier, 0);
421         if (r < 0) {
422             return r;
423         }
424         virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd);
425     } else {
426         virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
427         event_notifier_cleanup(notifier);
428     }
429 
430     if (vdc->guest_notifier_mask) {
431         vdc->guest_notifier_mask(vdev, n, !assign);
432     }
433 
434     return 0;
435 }
436 
437 static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
438                                            bool assign)
439 {
440     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
441     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
442     /* TODO: need to check if kvm-arm supports irqfd */
443     bool with_irqfd = false;
444     int r, n;
445 
446     nvqs = MIN(nvqs, VIRTIO_QUEUE_MAX);
447 
448     for (n = 0; n < nvqs; n++) {
449         if (!virtio_queue_get_num(vdev, n)) {
450             break;
451         }
452 
453         r = virtio_mmio_set_guest_notifier(d, n, assign, with_irqfd);
454         if (r < 0) {
455             goto assign_error;
456         }
457     }
458 
459     return 0;
460 
461 assign_error:
462     /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
463     assert(assign);
464     while (--n >= 0) {
465         virtio_mmio_set_guest_notifier(d, n, !assign, false);
466     }
467     return r;
468 }
469 
470 /* virtio-mmio device */
471 
472 static void virtio_mmio_realizefn(DeviceState *d, Error **errp)
473 {
474     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
475     SysBusDevice *sbd = SYS_BUS_DEVICE(d);
476 
477     qbus_create_inplace(&proxy->bus, sizeof(proxy->bus), TYPE_VIRTIO_MMIO_BUS,
478                         d, NULL);
479     sysbus_init_irq(sbd, &proxy->irq);
480     memory_region_init_io(&proxy->iomem, OBJECT(d), &virtio_mem_ops, proxy,
481                           TYPE_VIRTIO_MMIO, 0x200);
482     sysbus_init_mmio(sbd, &proxy->iomem);
483 }
484 
485 static void virtio_mmio_class_init(ObjectClass *klass, void *data)
486 {
487     DeviceClass *dc = DEVICE_CLASS(klass);
488 
489     dc->realize = virtio_mmio_realizefn;
490     dc->reset = virtio_mmio_reset;
491     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
492 }
493 
494 static const TypeInfo virtio_mmio_info = {
495     .name          = TYPE_VIRTIO_MMIO,
496     .parent        = TYPE_SYS_BUS_DEVICE,
497     .instance_size = sizeof(VirtIOMMIOProxy),
498     .class_init    = virtio_mmio_class_init,
499 };
500 
501 /* virtio-mmio-bus. */
502 
503 static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data)
504 {
505     BusClass *bus_class = BUS_CLASS(klass);
506     VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
507 
508     k->notify = virtio_mmio_update_irq;
509     k->save_config = virtio_mmio_save_config;
510     k->load_config = virtio_mmio_load_config;
511     k->set_guest_notifiers = virtio_mmio_set_guest_notifiers;
512     k->ioeventfd_started = virtio_mmio_ioeventfd_started;
513     k->ioeventfd_set_started = virtio_mmio_ioeventfd_set_started;
514     k->ioeventfd_disabled = virtio_mmio_ioeventfd_disabled;
515     k->ioeventfd_set_disabled = virtio_mmio_ioeventfd_set_disabled;
516     k->ioeventfd_assign = virtio_mmio_ioeventfd_assign;
517     k->has_variable_vring_alignment = true;
518     bus_class->max_dev = 1;
519 }
520 
521 static const TypeInfo virtio_mmio_bus_info = {
522     .name          = TYPE_VIRTIO_MMIO_BUS,
523     .parent        = TYPE_VIRTIO_BUS,
524     .instance_size = sizeof(VirtioBusState),
525     .class_init    = virtio_mmio_bus_class_init,
526 };
527 
528 static void virtio_mmio_register_types(void)
529 {
530     type_register_static(&virtio_mmio_bus_info);
531     type_register_static(&virtio_mmio_info);
532 }
533 
534 type_init(virtio_mmio_register_types)
535