These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / seabios / src / hw / virtio-pci.c
1 /* virtio-pci.c - pci interface for virtio interface
2  *
3  * (c) Copyright 2008 Bull S.A.S.
4  *
5  *  Author: Laurent Vivier <Laurent.Vivier@bull.net>
6  *
7  * some parts from Linux Virtio PCI driver
8  *
9  *  Copyright IBM Corp. 2007
10  *  Authors: Anthony Liguori  <aliguori@us.ibm.com>
11  *
12  *  Adopted for Seabios: Gleb Natapov <gleb@redhat.com>
13  *
14  * This work is licensed under the terms of the GNU LGPLv3
15  * See the COPYING file in the top-level directory.
16  */
17
18 #include "config.h" // CONFIG_DEBUG_LEVEL
19 #include "malloc.h" // free
20 #include "output.h" // dprintf
21 #include "pci.h" // pci_config_readl
22 #include "pci_regs.h" // PCI_BASE_ADDRESS_0
23 #include "string.h" // memset
24 #include "virtio-pci.h"
25 #include "virtio-ring.h"
26
27 u64 vp_get_features(struct vp_device *vp)
28 {
29     u32 f0, f1;
30
31     if (vp->use_modern) {
32         vp_write(&vp->common, virtio_pci_common_cfg, device_feature_select, 0);
33         f0 = vp_read(&vp->common, virtio_pci_common_cfg, device_feature);
34         vp_write(&vp->common, virtio_pci_common_cfg, device_feature_select, 1);
35         f1 = vp_read(&vp->common, virtio_pci_common_cfg, device_feature);
36     } else {
37         f0 = vp_read(&vp->legacy, virtio_pci_legacy, host_features);
38         f1 = 0;
39     }
40     return ((u64)f1 << 32) | f0;
41 }
42
43 void vp_set_features(struct vp_device *vp, u64 features)
44 {
45     u32 f0, f1;
46
47     f0 = features;
48     f1 = features >> 32;
49
50     if (vp->use_modern) {
51         vp_write(&vp->common, virtio_pci_common_cfg, guest_feature_select, 0);
52         vp_write(&vp->common, virtio_pci_common_cfg, guest_feature, f0);
53         vp_write(&vp->common, virtio_pci_common_cfg, guest_feature_select, 1);
54         vp_write(&vp->common, virtio_pci_common_cfg, guest_feature, f1);
55     } else {
56         vp_write(&vp->legacy, virtio_pci_legacy, guest_features, f0);
57     }
58 }
59
60 u8 vp_get_status(struct vp_device *vp)
61 {
62     if (vp->use_modern) {
63         return vp_read(&vp->common, virtio_pci_common_cfg, device_status);
64     } else {
65         return vp_read(&vp->legacy, virtio_pci_legacy, status);
66     }
67 }
68
69 void vp_set_status(struct vp_device *vp, u8 status)
70 {
71     if (status == 0)        /* reset */
72         return;
73     if (vp->use_modern) {
74         vp_write(&vp->common, virtio_pci_common_cfg, device_status, status);
75     } else {
76         vp_write(&vp->legacy, virtio_pci_legacy, status, status);
77     }
78 }
79
80 u8 vp_get_isr(struct vp_device *vp)
81 {
82     if (vp->use_modern) {
83         return vp_read(&vp->isr, virtio_pci_isr, isr);
84     } else {
85         return vp_read(&vp->legacy, virtio_pci_legacy, isr);
86     }
87 }
88
89 void vp_reset(struct vp_device *vp)
90 {
91     if (vp->use_modern) {
92         vp_write(&vp->common, virtio_pci_common_cfg, device_status, 0);
93         vp_read(&vp->isr, virtio_pci_isr, isr);
94     } else {
95         vp_write(&vp->legacy, virtio_pci_legacy, status, 0);
96         vp_read(&vp->legacy, virtio_pci_legacy, isr);
97     }
98 }
99
100 void vp_notify(struct vp_device *vp, struct vring_virtqueue *vq)
101 {
102     if (vp->use_modern) {
103         u32 addr = vp->notify.addr +
104             vq->queue_notify_off *
105             vp->notify_off_multiplier;
106         if (vp->notify.is_io) {
107             outw(vq->queue_index, addr);
108         } else {
109             writew((void*)addr, vq->queue_index);
110         }
111         dprintf(9, "vp notify %x (%d) -- 0x%x\n",
112                 addr, 2, vq->queue_index);
113     } else {
114         vp_write(&vp->legacy, virtio_pci_legacy, queue_notify, vq->queue_index);
115     }
116 }
117
118 int vp_find_vq(struct vp_device *vp, int queue_index,
119                struct vring_virtqueue **p_vq)
120 {
121    u16 num;
122
123    ASSERT32FLAT();
124    struct vring_virtqueue *vq = *p_vq = memalign_high(PAGE_SIZE, sizeof(*vq));
125    if (!vq) {
126        warn_noalloc();
127        goto fail;
128    }
129    memset(vq, 0, sizeof(*vq));
130
131
132    /* select the queue */
133    if (vp->use_modern) {
134        vp_write(&vp->common, virtio_pci_common_cfg, queue_select, queue_index);
135    } else {
136        vp_write(&vp->legacy, virtio_pci_legacy, queue_sel, queue_index);
137    }
138
139    /* check if the queue is available */
140    if (vp->use_modern) {
141        num = vp_read(&vp->common, virtio_pci_common_cfg, queue_size);
142        if (num > MAX_QUEUE_NUM) {
143            vp_write(&vp->common, virtio_pci_common_cfg, queue_size,
144                     MAX_QUEUE_NUM);
145            num = vp_read(&vp->common, virtio_pci_common_cfg, queue_size);
146        }
147    } else {
148        num = vp_read(&vp->legacy, virtio_pci_legacy, queue_num);
149    }
150    if (!num) {
151        dprintf(1, "ERROR: queue size is 0\n");
152        goto fail;
153    }
154    if (num > MAX_QUEUE_NUM) {
155        dprintf(1, "ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM);
156        goto fail;
157    }
158
159    /* check if the queue is already active */
160    if (vp->use_modern) {
161        if (vp_read(&vp->common, virtio_pci_common_cfg, queue_enable)) {
162            dprintf(1, "ERROR: queue already active\n");
163            goto fail;
164        }
165    } else {
166        if (vp_read(&vp->legacy, virtio_pci_legacy, queue_pfn)) {
167            dprintf(1, "ERROR: queue already active\n");
168            goto fail;
169        }
170    }
171    vq->queue_index = queue_index;
172
173    /* initialize the queue */
174    struct vring * vr = &vq->vring;
175    vring_init(vr, num, (unsigned char*)&vq->queue);
176
177    /* activate the queue
178     *
179     * NOTE: vr->desc is initialized by vring_init()
180     */
181
182    if (vp->use_modern) {
183        vp_write(&vp->common, virtio_pci_common_cfg, queue_desc_lo,
184                 (unsigned long)virt_to_phys(vr->desc));
185        vp_write(&vp->common, virtio_pci_common_cfg, queue_desc_hi, 0);
186        vp_write(&vp->common, virtio_pci_common_cfg, queue_avail_lo,
187                 (unsigned long)virt_to_phys(vr->avail));
188        vp_write(&vp->common, virtio_pci_common_cfg, queue_avail_hi, 0);
189        vp_write(&vp->common, virtio_pci_common_cfg, queue_used_lo,
190                 (unsigned long)virt_to_phys(vr->used));
191        vp_write(&vp->common, virtio_pci_common_cfg, queue_used_hi, 0);
192        vp_write(&vp->common, virtio_pci_common_cfg, queue_enable, 1);
193        vq->queue_notify_off = vp_read(&vp->common, virtio_pci_common_cfg,
194                                       queue_notify_off);
195    } else {
196        vp_write(&vp->legacy, virtio_pci_legacy, queue_pfn,
197                 (unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT);
198    }
199    return num;
200
201 fail:
202    free(vq);
203    *p_vq = NULL;
204    return -1;
205 }
206
207 void vp_init_simple(struct vp_device *vp, struct pci_device *pci)
208 {
209     u8 cap = pci_find_capability(pci, PCI_CAP_ID_VNDR, 0);
210     struct vp_cap *vp_cap;
211     u32 addr, offset, mul;
212     u8 type;
213
214     memset(vp, 0, sizeof(*vp));
215     while (cap != 0) {
216         type = pci_config_readb(pci->bdf, cap +
217                                 offsetof(struct virtio_pci_cap, cfg_type));
218         switch (type) {
219         case VIRTIO_PCI_CAP_COMMON_CFG:
220             vp_cap = &vp->common;
221             break;
222         case VIRTIO_PCI_CAP_NOTIFY_CFG:
223             vp_cap = &vp->notify;
224             mul = offsetof(struct virtio_pci_notify_cap, notify_off_multiplier);
225             vp->notify_off_multiplier = pci_config_readl(pci->bdf, cap + mul);
226             break;
227         case VIRTIO_PCI_CAP_ISR_CFG:
228             vp_cap = &vp->isr;
229             break;
230         case VIRTIO_PCI_CAP_DEVICE_CFG:
231             vp_cap = &vp->device;
232             break;
233         default:
234             vp_cap = NULL;
235             break;
236         }
237         if (vp_cap && !vp_cap->cap) {
238             vp_cap->cap = cap;
239             vp_cap->bar = pci_config_readb(pci->bdf, cap +
240                                            offsetof(struct virtio_pci_cap, bar));
241             offset = pci_config_readl(pci->bdf, cap +
242                                       offsetof(struct virtio_pci_cap, offset));
243             addr = pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_0 + 4 * vp_cap->bar);
244             if (addr & PCI_BASE_ADDRESS_SPACE_IO) {
245                 vp_cap->is_io = 1;
246                 addr &= PCI_BASE_ADDRESS_IO_MASK;
247             } else {
248                 vp_cap->is_io = 0;
249                 addr &= PCI_BASE_ADDRESS_MEM_MASK;
250             }
251             vp_cap->addr = addr + offset;
252             dprintf(3, "pci dev %x:%x virtio cap at 0x%x type %d "
253                     "bar %d at 0x%08x off +0x%04x [%s]\n",
254                     pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
255                     vp_cap->cap, type, vp_cap->bar, addr, offset,
256                     vp_cap->is_io ? "io" : "mmio");
257         }
258
259         cap = pci_find_capability(pci, PCI_CAP_ID_VNDR, cap);
260     }
261
262     if (vp->common.cap && vp->notify.cap && vp->isr.cap && vp->device.cap) {
263         dprintf(1, "pci dev %x:%x using modern (1.0) virtio mode\n",
264                 pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf));
265         vp->use_modern = 1;
266     } else {
267         dprintf(1, "pci dev %x:%x using legacy (0.9.5) virtio mode\n",
268                 pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf));
269         vp->legacy.bar = 0;
270         vp->legacy.addr = pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_0) &
271             PCI_BASE_ADDRESS_IO_MASK;
272         vp->legacy.is_io = 1;
273     }
274
275     vp_reset(vp);
276     pci_config_maskw(pci->bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER);
277     vp_set_status(vp, VIRTIO_CONFIG_S_ACKNOWLEDGE |
278                   VIRTIO_CONFIG_S_DRIVER );
279 }