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 19int 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