Initialize
[sdk/emulator/qemu.git] / roms / seabios / src / 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 "virtio-ring.h"
19 #include "virtio-pci.h"
20 #include "config.h" // CONFIG_DEBUG_LEVEL
21 #include "util.h" // dprintf
22
23 int vp_find_vq(unsigned int ioaddr, int queue_index,
24                struct vring_virtqueue *vq)
25 {
26    struct vring * vr = &vq->vring;
27    u16 num;
28
29    ASSERT32FLAT();
30    /* select the queue */
31
32    outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL);
33
34    /* check if the queue is available */
35
36    num = inw(ioaddr + VIRTIO_PCI_QUEUE_NUM);
37    if (!num) {
38        dprintf(1, "ERROR: queue size is 0\n");
39        return -1;
40    }
41
42    if (num > MAX_QUEUE_NUM) {
43        dprintf(1, "ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM);
44        return -1;
45    }
46
47    /* check if the queue is already active */
48
49    if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) {
50        dprintf(1, "ERROR: queue already active\n");
51        return -1;
52    }
53
54    vq->queue_index = queue_index;
55
56    /* initialize the queue */
57
58    vring_init(vr, num, (unsigned char*)&vq->queue);
59
60    /* activate the queue
61     *
62     * NOTE: vr->desc is initialized by vring_init()
63     */
64
65    outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT,
66         ioaddr + VIRTIO_PCI_QUEUE_PFN);
67
68    return num;
69 }