virtio_lib.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * This file is part of the Harvey operating system. It is subject to the
  3. * license terms of the GNU GPL v2 in LICENSE.gpl found in the top-level
  4. * directory of this distribution and at http://www.gnu.org/licenses/gpl-2.0.txt
  5. *
  6. * No part of Harvey operating system, including this file, may be copied,
  7. * modified, propagated, or distributed except according to the terms
  8. * contained in the LICENSE.gpl file.
  9. */
  10. // Definitions for the virtqueue handling functions library.
  11. // Specific device control structures. They are preallocated during the driver
  12. // initialization and remain mainly constant during the kernel uptime.
  13. struct virtq;
  14. typedef struct vqctl // per-device control structure
  15. {
  16. Pcidev *pci; // PCI device descriptor
  17. uint32_t port; // base I/O port for the legacy port-based interface
  18. uint32_t feat; // host features
  19. uint32_t nqs; // virt queues count
  20. struct virtq **vqs; // virt queues descriptors
  21. uint32_t dcfglen; // device config area length
  22. uint32_t dcfgoff; // device config area offset (20 or 24)
  23. long dcmtime; // device config area modification time
  24. char devname[32]; // device name to show in port and interrupt allocations
  25. } Vqctl;
  26. typedef struct rock {
  27. int done;
  28. Rendez *sleep;
  29. } Rock;
  30. // Customized virtqueue
  31. typedef struct virtq {
  32. struct vring vr; // vring descriptor per spec
  33. uint8_t *vq; // vring data shared between host and guest
  34. uint16_t lastused;
  35. uint16_t waiting;
  36. Lock l;
  37. uint free;
  38. uint nfree;
  39. void *pdev; // use this to reference the virtio device control structure which is per-driver
  40. int idx; // driver use only, index of the queue per device
  41. void *pqdata; // per-queue private data (may be shared between queues of the same device)
  42. Rock *rock[]; // array of pointers to the waiting processes, length same as queue length
  43. } Virtq;
  44. // Common virtqueue functions and macros.
  45. int getdescr(Virtq *q, int n, uint16_t *descr);
  46. int queuedescr(Virtq *q, int n, uint16_t *descr);
  47. void reldescr(Virtq *q, int n, uint16_t *descr);
  48. int initvdevs(Vqctl **vcs);
  49. int vqalloc(Virtq **pq, int qs);
  50. void finalinitvdev(Vqctl *vc);
  51. int readvdevcfg(Vqctl *vc, void *va, int32_t n, int64_t offset);
  52. Vqctl *vdevbyidx(uint32_t idx);
  53. uint32_t vdevfeat(Vqctl *vc, uint32_t(*ffltr)(uint32_t));
  54. uint32_t getvdevnum(void);
  55. uint32_t getvdevsbypciid(int pciid, Vqctl **vqs, uint32_t n);
  56. static inline struct vring_desc * q2descr(Virtq *q, int i) { return q->vr.desc + i; }
  57. // Unified QID conversions between values and device/queue indices. We allocate bits:
  58. // 0 - 3 for QID type (specific to each driver)
  59. // 4 - 15 for device index (to use with vdevbyidx)
  60. // 16 - 32 for queue index within device
  61. // Extract QID type
  62. #define TYPE(q) ((uint32_t)(q).path & 0x0F)
  63. // Extract device index
  64. #define DEV(q) ((uint32_t)(((q).path >> 4) & 0x0FFF))
  65. // Extract queue index
  66. #define VQ(q) ((uint32_t)(((q).path >> 16) & 0x0FFFF))
  67. // Construct a non-queue aware QID (to address a per-device file)
  68. #define QID(c, t) ((((c) & 0x0FFF)<<4) | ((t) & 0x0F))
  69. // Construct a queue-aware QID (to address a per-queue file)
  70. #define VQQID(q, c, t) ((((q) & 0x0FFFF)<<16) | (((c) & 0x0FFF)<<4) | ((t) & 0x0F))