|
|
1.1 root 1: /* virtio-pci.c - pci interface for virtio interface
2: *
3: * (c) Copyright 2008 Bull S.A.S.
4: *
5: * Author: Laurent Vivier <[email protected]>
6: *
7: * some parts from Linux Virtio PCI driver
8: *
9: * Copyright IBM Corp. 2007
10: * Authors: Anthony Liguori <[email protected]>
11: *
12: * Adopted for Seabios: Gleb Natapov <[email protected]>
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
1.1.1.2 ! root 22: #include "pci.h" // pci_config_readl
! 23: #include "pci_regs.h" // PCI_BASE_ADDRESS_0
1.1 root 24:
25: int vp_find_vq(unsigned int ioaddr, int queue_index,
1.1.1.2 ! root 26: struct vring_virtqueue **p_vq)
1.1 root 27: {
28: u16 num;
29:
30: ASSERT32FLAT();
1.1.1.2 ! root 31: struct vring_virtqueue *vq = *p_vq = memalign_low(PAGE_SIZE, sizeof(*vq));
! 32: if (!vq) {
! 33: warn_noalloc();
! 34: goto fail;
! 35: }
! 36: memset(vq, 0, sizeof(*vq));
! 37:
1.1 root 38: /* select the queue */
39:
40: outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL);
41:
42: /* check if the queue is available */
43:
44: num = inw(ioaddr + VIRTIO_PCI_QUEUE_NUM);
45: if (!num) {
46: dprintf(1, "ERROR: queue size is 0\n");
1.1.1.2 ! root 47: goto fail;
1.1 root 48: }
49:
50: if (num > MAX_QUEUE_NUM) {
51: dprintf(1, "ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM);
1.1.1.2 ! root 52: goto fail;
1.1 root 53: }
54:
55: /* check if the queue is already active */
56:
57: if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) {
58: dprintf(1, "ERROR: queue already active\n");
1.1.1.2 ! root 59: goto fail;
1.1 root 60: }
61:
62: vq->queue_index = queue_index;
63:
64: /* initialize the queue */
65:
1.1.1.2 ! root 66: struct vring * vr = &vq->vring;
1.1 root 67: vring_init(vr, num, (unsigned char*)&vq->queue);
68:
69: /* activate the queue
70: *
71: * NOTE: vr->desc is initialized by vring_init()
72: */
73:
74: outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT,
75: ioaddr + VIRTIO_PCI_QUEUE_PFN);
76:
77: return num;
1.1.1.2 ! root 78:
! 79: fail:
! 80: free(vq);
! 81: *p_vq = NULL;
! 82: return -1;
! 83: }
! 84:
! 85: u16 vp_init_simple(u16 bdf)
! 86: {
! 87: u16 ioaddr = pci_config_readl(bdf, PCI_BASE_ADDRESS_0) &
! 88: PCI_BASE_ADDRESS_IO_MASK;
! 89:
! 90: vp_reset(ioaddr);
! 91: vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
! 92: VIRTIO_CONFIG_S_DRIVER );
! 93: return ioaddr;
1.1 root 94: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.