/* * Generic virtio library for MINIX 3 * * Copyright (c) 2013, A. Welzel, * * This software is released under the BSD license. See the LICENSE file * included in the main directory of this source distribution for the * license terms and conditions. */ #ifndef _MINIX_VIRTIO_H #define _MINIX_VIRTIO_H 1 #include #define VIRTIO_VENDOR_ID 0x1AF4 #define VIRTIO_HOST_F_OFF 0x0000 #define VIRTIO_GUEST_F_OFF 0x0004 #define VIRTIO_QADDR_OFF 0x0008 #define VIRTIO_QSIZE_OFF 0x000C #define VIRTIO_QSEL_OFF 0x000E #define VIRTIO_QNOTFIY_OFF 0x0010 #define VIRTIO_DEV_STATUS_OFF 0x0012 #define VIRTIO_ISR_STATUS_OFF 0x0013 #define VIRTIO_DEV_SPECIFIC_OFF 0x0014 /* if msi is enabled, device specific headers shift by 4 */ #define VIRTIO_MSI_ADD_OFF 0x0004 #define VIRTIO_STATUS_ACK 0x01 #define VIRTIO_STATUS_DRV 0x02 #define VIRTIO_STATUS_DRV_OK 0x04 #define VIRTIO_STATUS_FAIL 0x80 /* Feature description */ struct virtio_feature { const char *name; u8_t bit; u8_t host_support; u8_t guest_support; }; /* Forward declaration of struct virtio_device. * * This structure is opaque to the caller. */ struct virtio_device; /* Find a virtio device with subdevice id subdevid. Returns a pointer * to an opaque virtio_device instance. */ struct virtio_device *virtio_setup_device(u16_t subdevid, const char *name, struct virtio_feature *features, int feature_count, int threads, int skip); /* Attempt to allocate queue_cnt memory for queues */ int virtio_alloc_queues(struct virtio_device *dev, int num_queues); /* Register the IRQ policy and indicate to the host we are ready to go */ void virtio_device_ready(struct virtio_device *dev); /* Unregister the IRQ and reset the device */ void virtio_reset_device(struct virtio_device *dev); /* Free the memory used by all queues */ void virtio_free_queues(struct virtio_device *dev); /* Free all memory allocated for the device (except the queue memory, * which has to be freed before with virtio_free_queues()). * * Don't touch the device afterwards! This is like free(dev). */ void virtio_free_device(struct virtio_device *dev); /* Feature helpers */ int virtio_guest_supports(struct virtio_device *dev, int bit); int virtio_host_supports(struct virtio_device *dev, int bit); /* * Use num vumap_phys elements and chain these as vring_desc elements * into the vring. * * Kick the queue if needed. * * data is opaque and returned by virtio_from_queue() when the host * processed the descriptor chain. * * Note: The last bit of vp_addr is used to flag whether an iovec is * writable. This implies that only word aligned buffers can be * used. */ int virtio_to_queue(struct virtio_device *dev, int qidx, struct vumap_phys *bufs, size_t num, void *data); /* * If the host used a chain of descriptors, return 0 and set data * as was given to virtio_to_queue(). If the host has not processed * any element returns -1. */ int virtio_from_queue(struct virtio_device *dev, int qidx, void **data); /* IRQ related functions */ void virtio_irq_enable(struct virtio_device *dev); void virtio_irq_disable(struct virtio_device *dev); /* Checks the ISR field of the device and returns true if * the interrupt was for this device. */ int virtio_had_irq(struct virtio_device *dev); u32_t virtio_read32(struct virtio_device *dev, off_t offset); u16_t virtio_read16(struct virtio_device *dev, off_t offset); u8_t virtio_read8(struct virtio_device *dev, off_t offset); void virtio_write32(struct virtio_device *dev, off_t offset, u32_t val); void virtio_write16(struct virtio_device *dev, off_t offset, u16_t val); void virtio_write8(struct virtio_device *dev, off_t offset, u8_t val); /* * Device specific reads take MSI offset into account and all reads * are at offset 20. * * Something like: * read(off) --> readX(20 + (msi ? 4 : 0) + off) */ u32_t virtio_sread32(struct virtio_device *dev, off_t offset); u16_t virtio_sread16(struct virtio_device *dev, off_t offset); u8_t virtio_sread8(struct virtio_device *dev, off_t offset); void virtio_swrite32(struct virtio_device *dev, off_t offset, u32_t val); void virtio_swrite16(struct virtio_device *dev, off_t offset, u16_t val); void virtio_swrite8(struct virtio_device *dev, off_t offset, u8_t val); #endif /* _MINIX_VIRTIO_H */