You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

virtio-pci.c 1.4KB

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