• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
13 
14 #include "etherboot.h"
15 #include "gpxe/io.h"
16 #include "gpxe/virtio-ring.h"
17 #include "gpxe/virtio-pci.h"
18 
vp_find_vq(unsigned int ioaddr,int queue_index,struct vring_virtqueue * vq)19 int vp_find_vq(unsigned int ioaddr, int queue_index,
20                struct vring_virtqueue *vq)
21 {
22    struct vring * vr = &vq->vring;
23    u16 num;
24 
25    /* select the queue */
26 
27    outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL);
28 
29    /* check if the queue is available */
30 
31    num = inw(ioaddr + VIRTIO_PCI_QUEUE_NUM);
32    if (!num) {
33            printf("ERROR: queue size is 0\n");
34            return -1;
35    }
36 
37    if (num > MAX_QUEUE_NUM) {
38            printf("ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM);
39            return -1;
40    }
41 
42    /* check if the queue is already active */
43 
44    if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) {
45            printf("ERROR: queue already active\n");
46            return -1;
47    }
48 
49    vq->queue_index = queue_index;
50 
51    /* initialize the queue */
52 
53    vring_init(vr, num, (unsigned char*)&vq->queue);
54 
55    /* activate the queue
56     *
57     * NOTE: vr->desc is initialized by vring_init()
58     */
59 
60    outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT,
61         ioaddr + VIRTIO_PCI_QUEUE_PFN);
62 
63    return num;
64 }
65