1 /* virtio-pci.c - pci interface for virtio interface
3 * (c) Copyright 2008 Bull S.A.S.
5 * Author: Laurent Vivier <Laurent.Vivier@bull.net>
7 * some parts from Linux Virtio PCI driver
9 * Copyright IBM Corp. 2007
10 * Authors: Anthony Liguori <aliguori@us.ibm.com>
12 * Adopted for Seabios: Gleb Natapov <gleb@redhat.com>
14 * This work is licensed under the terms of the GNU LGPLv3
15 * See the COPYING file in the top-level directory.
18 #include "virtio-ring.h"
19 #include "virtio-pci.h"
20 #include "config.h" // CONFIG_DEBUG_LEVEL
21 #include "util.h" // dprintf
22 #include "pci.h" // pci_config_readl
23 #include "pci_regs.h" // PCI_BASE_ADDRESS_0
25 int vp_find_vq(unsigned int ioaddr, int queue_index,
26 struct vring_virtqueue **p_vq)
31 struct vring_virtqueue *vq = *p_vq = memalign_low(PAGE_SIZE, sizeof(*vq));
36 memset(vq, 0, sizeof(*vq));
38 /* select the queue */
40 outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL);
42 /* check if the queue is available */
44 num = inw(ioaddr + VIRTIO_PCI_QUEUE_NUM);
46 dprintf(1, "ERROR: queue size is 0\n");
50 if (num > MAX_QUEUE_NUM) {
51 dprintf(1, "ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM);
55 /* check if the queue is already active */
57 if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) {
58 dprintf(1, "ERROR: queue already active\n");
62 vq->queue_index = queue_index;
64 /* initialize the queue */
66 struct vring * vr = &vq->vring;
67 vring_init(vr, num, (unsigned char*)&vq->queue);
71 * NOTE: vr->desc is initialized by vring_init()
74 outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT,
75 ioaddr + VIRTIO_PCI_QUEUE_PFN);
85 u16 vp_init_simple(u16 bdf)
87 u16 ioaddr = pci_config_readl(bdf, PCI_BASE_ADDRESS_0) &
88 PCI_BASE_ADDRESS_IO_MASK;
91 vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
92 VIRTIO_CONFIG_S_DRIVER );