aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPawel Moll <pawel.moll@arm.com>2015-01-22 23:15:55 -0500
committerRusty Russell <rusty@rustcorp.com.au>2015-01-22 23:27:10 -0500
commit1862ee22ce2e28087299aebb6556a5cdc122d0ef (patch)
treef28c2d0aae6d7e9bde82b269d09da72d727f8522
parent76545f066d2a85464a9f81de2e159b199cc2942b (diff)
virtio-mmio: Update the device to OASIS spec version
This patch add a support for second version of the virtio-mmio device, which follows OASIS "Virtual I/O Device (VIRTIO) Version 1.0" specification. Main changes: 1. The control register symbolic names use the new device/driver nomenclature rather than the old guest/host one. 2. The driver detect the device version (version 1 is the pre-OASIS spec, version 2 is compatible with fist revision of the OASIS spec) and drives the device accordingly. 3. New version uses direct addressing (64 bit address split into two low/high register) instead of the guest page size based one, and addresses each part of the queue (descriptors, available, used) separately. 4. The device activity is now explicitly triggered by writing to the "queue ready" register. 5. Whole 64 bit features are properly handled now (both ways). Signed-off-by: Pawel Moll <pawel.moll@arm.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--drivers/virtio/virtio_mmio.c131
-rw-r--r--include/linux/virtio_mmio.h44
2 files changed, 118 insertions, 57 deletions
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 00d115b22bd8..cad569890908 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Virtio memory mapped device driver 2 * Virtio memory mapped device driver
3 * 3 *
4 * Copyright 2011, ARM Ltd. 4 * Copyright 2011-2014, ARM Ltd.
5 * 5 *
6 * This module allows virtio devices to be used over a virtual, memory mapped 6 * This module allows virtio devices to be used over a virtual, memory mapped
7 * platform device. 7 * platform device.
@@ -50,36 +50,6 @@
50 * 50 *
51 * 51 *
52 * 52 *
53 * Registers layout (all 32-bit wide):
54 *
55 * offset d. name description
56 * ------ -- ---------------- -----------------
57 *
58 * 0x000 R MagicValue Magic value "virt"
59 * 0x004 R Version Device version (current max. 1)
60 * 0x008 R DeviceID Virtio device ID
61 * 0x00c R VendorID Virtio vendor ID
62 *
63 * 0x010 R HostFeatures Features supported by the host
64 * 0x014 W HostFeaturesSel Set of host features to access via HostFeatures
65 *
66 * 0x020 W GuestFeatures Features activated by the guest
67 * 0x024 W GuestFeaturesSel Set of activated features to set via GuestFeatures
68 * 0x028 W GuestPageSize Size of guest's memory page in bytes
69 *
70 * 0x030 W QueueSel Queue selector
71 * 0x034 R QueueNumMax Maximum size of the currently selected queue
72 * 0x038 W QueueNum Queue size for the currently selected queue
73 * 0x03c W QueueAlign Used Ring alignment for the current queue
74 * 0x040 RW QueuePFN PFN for the currently selected queue
75 *
76 * 0x050 W QueueNotify Queue notifier
77 * 0x060 R InterruptStatus Interrupt status register
78 * 0x064 W InterruptACK Interrupt acknowledge register
79 * 0x070 RW Status Device status register
80 *
81 * 0x100+ RW Device-specific configuration space
82 *
83 * Based on Virtio PCI driver by Anthony Liguori, copyright IBM Corp. 2007 53 * Based on Virtio PCI driver by Anthony Liguori, copyright IBM Corp. 2007
84 * 54 *
85 * This work is licensed under the terms of the GNU GPL, version 2 or later. 55 * This work is licensed under the terms of the GNU GPL, version 2 or later.
@@ -145,11 +115,16 @@ struct virtio_mmio_vq_info {
145static u64 vm_get_features(struct virtio_device *vdev) 115static u64 vm_get_features(struct virtio_device *vdev)
146{ 116{
147 struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); 117 struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
118 u64 features;
119
120 writel(1, vm_dev->base + VIRTIO_MMIO_DEVICE_FEATURES_SEL);
121 features = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_FEATURES);
122 features <<= 32;
148 123
149 /* TODO: Features > 32 bits */ 124 writel(0, vm_dev->base + VIRTIO_MMIO_DEVICE_FEATURES_SEL);
150 writel(0, vm_dev->base + VIRTIO_MMIO_HOST_FEATURES_SEL); 125 features |= readl(vm_dev->base + VIRTIO_MMIO_DEVICE_FEATURES);
151 126
152 return readl(vm_dev->base + VIRTIO_MMIO_HOST_FEATURES); 127 return features;
153} 128}
154 129
155static int vm_finalize_features(struct virtio_device *vdev) 130static int vm_finalize_features(struct virtio_device *vdev)
@@ -159,11 +134,20 @@ static int vm_finalize_features(struct virtio_device *vdev)
159 /* Give virtio_ring a chance to accept features. */ 134 /* Give virtio_ring a chance to accept features. */
160 vring_transport_features(vdev); 135 vring_transport_features(vdev);
161 136
162 /* Make sure we don't have any features > 32 bits! */ 137 /* Make sure there is are no mixed devices */
163 BUG_ON((u32)vdev->features != vdev->features); 138 if (vm_dev->version == 2 &&
139 !__virtio_test_bit(vdev, VIRTIO_F_VERSION_1)) {
140 dev_err(&vdev->dev, "New virtio-mmio devices (version 2) must provide VIRTIO_F_VERSION_1 feature!\n");
141 return -EINVAL;
142 }
143
144 writel(1, vm_dev->base + VIRTIO_MMIO_DRIVER_FEATURES_SEL);
145 writel((u32)(vdev->features >> 32),
146 vm_dev->base + VIRTIO_MMIO_DRIVER_FEATURES);
164 147
165 writel(0, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES_SEL); 148 writel(0, vm_dev->base + VIRTIO_MMIO_DRIVER_FEATURES_SEL);
166 writel(vdev->features, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES); 149 writel((u32)vdev->features,
150 vm_dev->base + VIRTIO_MMIO_DRIVER_FEATURES);
167 151
168 return 0; 152 return 0;
169} 153}
@@ -275,7 +259,12 @@ static void vm_del_vq(struct virtqueue *vq)
275 259
276 /* Select and deactivate the queue */ 260 /* Select and deactivate the queue */
277 writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL); 261 writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
278 writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN); 262 if (vm_dev->version == 1) {
263 writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
264 } else {
265 writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
266 WARN_ON(readl(vm_dev->base + VIRTIO_MMIO_QUEUE_READY));
267 }
279 268
280 size = PAGE_ALIGN(vring_size(info->num, VIRTIO_MMIO_VRING_ALIGN)); 269 size = PAGE_ALIGN(vring_size(info->num, VIRTIO_MMIO_VRING_ALIGN));
281 free_pages_exact(info->queue, size); 270 free_pages_exact(info->queue, size);
@@ -312,7 +301,8 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
312 writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL); 301 writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
313 302
314 /* Queue shouldn't already be set up. */ 303 /* Queue shouldn't already be set up. */
315 if (readl(vm_dev->base + VIRTIO_MMIO_QUEUE_PFN)) { 304 if (readl(vm_dev->base + (vm_dev->version == 1 ?
305 VIRTIO_MMIO_QUEUE_PFN : VIRTIO_MMIO_QUEUE_READY))) {
316 err = -ENOENT; 306 err = -ENOENT;
317 goto error_available; 307 goto error_available;
318 } 308 }
@@ -356,13 +346,6 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
356 info->num /= 2; 346 info->num /= 2;
357 } 347 }
358 348
359 /* Activate the queue */
360 writel(info->num, vm_dev->base + VIRTIO_MMIO_QUEUE_NUM);
361 writel(VIRTIO_MMIO_VRING_ALIGN,
362 vm_dev->base + VIRTIO_MMIO_QUEUE_ALIGN);
363 writel(virt_to_phys(info->queue) >> PAGE_SHIFT,
364 vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
365
366 /* Create the vring */ 349 /* Create the vring */
367 vq = vring_new_virtqueue(index, info->num, VIRTIO_MMIO_VRING_ALIGN, vdev, 350 vq = vring_new_virtqueue(index, info->num, VIRTIO_MMIO_VRING_ALIGN, vdev,
368 true, info->queue, vm_notify, callback, name); 351 true, info->queue, vm_notify, callback, name);
@@ -371,6 +354,33 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
371 goto error_new_virtqueue; 354 goto error_new_virtqueue;
372 } 355 }
373 356
357 /* Activate the queue */
358 writel(info->num, vm_dev->base + VIRTIO_MMIO_QUEUE_NUM);
359 if (vm_dev->version == 1) {
360 writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_QUEUE_ALIGN);
361 writel(virt_to_phys(info->queue) >> PAGE_SHIFT,
362 vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
363 } else {
364 u64 addr;
365
366 addr = virt_to_phys(info->queue);
367 writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_DESC_LOW);
368 writel((u32)(addr >> 32),
369 vm_dev->base + VIRTIO_MMIO_QUEUE_DESC_HIGH);
370
371 addr = virt_to_phys(virtqueue_get_avail(vq));
372 writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_AVAIL_LOW);
373 writel((u32)(addr >> 32),
374 vm_dev->base + VIRTIO_MMIO_QUEUE_AVAIL_HIGH);
375
376 addr = virt_to_phys(virtqueue_get_used(vq));
377 writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_USED_LOW);
378 writel((u32)(addr >> 32),
379 vm_dev->base + VIRTIO_MMIO_QUEUE_USED_HIGH);
380
381 writel(1, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
382 }
383
374 vq->priv = info; 384 vq->priv = info;
375 info->vq = vq; 385 info->vq = vq;
376 386
@@ -381,7 +391,12 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
381 return vq; 391 return vq;
382 392
383error_new_virtqueue: 393error_new_virtqueue:
384 writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN); 394 if (vm_dev->version == 1) {
395 writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
396 } else {
397 writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
398 WARN_ON(readl(vm_dev->base + VIRTIO_MMIO_QUEUE_READY));
399 }
385 free_pages_exact(info->queue, size); 400 free_pages_exact(info->queue, size);
386error_alloc_pages: 401error_alloc_pages:
387 kfree(info); 402 kfree(info);
@@ -476,16 +491,32 @@ static int virtio_mmio_probe(struct platform_device *pdev)
476 491
477 /* Check device version */ 492 /* Check device version */
478 vm_dev->version = readl(vm_dev->base + VIRTIO_MMIO_VERSION); 493 vm_dev->version = readl(vm_dev->base + VIRTIO_MMIO_VERSION);
479 if (vm_dev->version != 1) { 494 if (vm_dev->version < 1 || vm_dev->version > 2) {
480 dev_err(&pdev->dev, "Version %ld not supported!\n", 495 dev_err(&pdev->dev, "Version %ld not supported!\n",
481 vm_dev->version); 496 vm_dev->version);
482 return -ENXIO; 497 return -ENXIO;
483 } 498 }
484 499
485 vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID); 500 vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID);
501 if (vm_dev->vdev.id.device == 0) {
502 /*
503 * virtio-mmio device with an ID 0 is a (dummy) placeholder
504 * with no function. End probing now with no error reported.
505 */
506 return -ENODEV;
507 }
486 vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID); 508 vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);
487 509
488 writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE); 510 /* Reject legacy-only IDs for version 2 devices */
511 if (vm_dev->version == 2 &&
512 virtio_device_is_legacy_only(vm_dev->vdev.id)) {
513 dev_err(&pdev->dev, "Version 2 not supported for devices %u!\n",
514 vm_dev->vdev.id.device);
515 return -ENODEV;
516 }
517
518 if (vm_dev->version == 1)
519 writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE);
489 520
490 platform_set_drvdata(pdev, vm_dev); 521 platform_set_drvdata(pdev, vm_dev);
491 522
diff --git a/include/linux/virtio_mmio.h b/include/linux/virtio_mmio.h
index 5c7b6f0daef8..c4b09689ab64 100644
--- a/include/linux/virtio_mmio.h
+++ b/include/linux/virtio_mmio.h
@@ -51,23 +51,29 @@
51/* Virtio vendor ID - Read Only */ 51/* Virtio vendor ID - Read Only */
52#define VIRTIO_MMIO_VENDOR_ID 0x00c 52#define VIRTIO_MMIO_VENDOR_ID 0x00c
53 53
54/* Bitmask of the features supported by the host 54/* Bitmask of the features supported by the device (host)
55 * (32 bits per set) - Read Only */ 55 * (32 bits per set) - Read Only */
56#define VIRTIO_MMIO_HOST_FEATURES 0x010 56#define VIRTIO_MMIO_DEVICE_FEATURES 0x010
57 57
58/* Host features set selector - Write Only */ 58/* Device (host) features set selector - Write Only */
59#define VIRTIO_MMIO_HOST_FEATURES_SEL 0x014 59#define VIRTIO_MMIO_DEVICE_FEATURES_SEL 0x014
60 60
61/* Bitmask of features activated by the guest 61/* Bitmask of features activated by the driver (guest)
62 * (32 bits per set) - Write Only */ 62 * (32 bits per set) - Write Only */
63#define VIRTIO_MMIO_GUEST_FEATURES 0x020 63#define VIRTIO_MMIO_DRIVER_FEATURES 0x020
64 64
65/* Activated features set selector - Write Only */ 65/* Activated features set selector - Write Only */
66#define VIRTIO_MMIO_GUEST_FEATURES_SEL 0x024 66#define VIRTIO_MMIO_DRIVER_FEATURES_SEL 0x024
67
68
69#ifndef VIRTIO_MMIO_NO_LEGACY /* LEGACY DEVICES ONLY! */
67 70
68/* Guest's memory page size in bytes - Write Only */ 71/* Guest's memory page size in bytes - Write Only */
69#define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028 72#define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028
70 73
74#endif
75
76
71/* Queue selector - Write Only */ 77/* Queue selector - Write Only */
72#define VIRTIO_MMIO_QUEUE_SEL 0x030 78#define VIRTIO_MMIO_QUEUE_SEL 0x030
73 79
@@ -77,12 +83,21 @@
77/* Queue size for the currently selected queue - Write Only */ 83/* Queue size for the currently selected queue - Write Only */
78#define VIRTIO_MMIO_QUEUE_NUM 0x038 84#define VIRTIO_MMIO_QUEUE_NUM 0x038
79 85
86
87#ifndef VIRTIO_MMIO_NO_LEGACY /* LEGACY DEVICES ONLY! */
88
80/* Used Ring alignment for the currently selected queue - Write Only */ 89/* Used Ring alignment for the currently selected queue - Write Only */
81#define VIRTIO_MMIO_QUEUE_ALIGN 0x03c 90#define VIRTIO_MMIO_QUEUE_ALIGN 0x03c
82 91
83/* Guest's PFN for the currently selected queue - Read Write */ 92/* Guest's PFN for the currently selected queue - Read Write */
84#define VIRTIO_MMIO_QUEUE_PFN 0x040 93#define VIRTIO_MMIO_QUEUE_PFN 0x040
85 94
95#endif
96
97
98/* Ready bit for the currently selected queue - Read Write */
99#define VIRTIO_MMIO_QUEUE_READY 0x044
100
86/* Queue notifier - Write Only */ 101/* Queue notifier - Write Only */
87#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 102#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050
88 103
@@ -95,6 +110,21 @@
95/* Device status register - Read Write */ 110/* Device status register - Read Write */
96#define VIRTIO_MMIO_STATUS 0x070 111#define VIRTIO_MMIO_STATUS 0x070
97 112
113/* Selected queue's Descriptor Table address, 64 bits in two halves */
114#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080
115#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084
116
117/* Selected queue's Available Ring address, 64 bits in two halves */
118#define VIRTIO_MMIO_QUEUE_AVAIL_LOW 0x090
119#define VIRTIO_MMIO_QUEUE_AVAIL_HIGH 0x094
120
121/* Selected queue's Used Ring address, 64 bits in two halves */
122#define VIRTIO_MMIO_QUEUE_USED_LOW 0x0a0
123#define VIRTIO_MMIO_QUEUE_USED_HIGH 0x0a4
124
125/* Configuration atomicity value */
126#define VIRTIO_MMIO_CONFIG_GENERATION 0x0fc
127
98/* The config space is defined by each driver as 128/* The config space is defined by each driver as
99 * the per-driver configuration space - Read Write */ 129 * the per-driver configuration space - Read Write */
100#define VIRTIO_MMIO_CONFIG 0x100 130#define VIRTIO_MMIO_CONFIG 0x100