| /****************************************************************************** |
| * Copyright (c) 2011 IBM Corporation |
| * All rights reserved. |
| * This program and the accompanying materials |
| * are made available under the terms of the BSD License |
| * which accompanies this distribution, and is available at |
| * http://www.opensource.org/licenses/bsd-license.php |
| * |
| * Contributors: |
| * IBM Corporation - initial implementation |
| *****************************************************************************/ |
| |
| #ifndef _LIBVIRTIO_H |
| #define _LIBVIRTIO_H |
| |
| #include <stdint.h> |
| |
| /* Device status bits */ |
| #define VIRTIO_STAT_ACKNOWLEDGE 1 |
| #define VIRTIO_STAT_DRIVER 2 |
| #define VIRTIO_STAT_DRIVER_OK 4 |
| #define VIRTIO_STAT_FEATURES_OK 8 |
| #define VIRTIO_STAT_NEEDS_RESET 64 |
| #define VIRTIO_STAT_FAILED 128 |
| |
| #define BIT(x) (1UL << (x)) |
| |
| /* VIRTIO 1.0 Device independent feature bits */ |
| #define VIRTIO_F_RING_INDIRECT_DESC BIT(28) |
| #define VIRTIO_F_RING_EVENT_IDX BIT(29) |
| #define VIRTIO_F_VERSION_1 BIT(32) |
| #define VIRTIO_F_IOMMU_PLATFORM BIT(33) |
| |
| #define VIRTIO_TIMEOUT 5000 /* 5 sec timeout */ |
| |
| /* Definitions for vring_desc.flags */ |
| #define VRING_DESC_F_NEXT 1 /* buffer continues via the next field */ |
| #define VRING_DESC_F_WRITE 2 /* buffer is write-only (otherwise read-only) */ |
| #define VRING_DESC_F_INDIRECT 4 /* buffer contains a list of buffer descriptors */ |
| |
| /* Descriptor table entry - see Virtio Spec chapter 2.3.2 */ |
| struct vring_desc { |
| uint64_t addr; /* Address (guest-physical) */ |
| uint32_t len; /* Length */ |
| uint16_t flags; /* The flags as indicated above */ |
| uint16_t next; /* Next field if flags & NEXT */ |
| }; |
| |
| /* Definitions for vring_avail.flags */ |
| #define VRING_AVAIL_F_NO_INTERRUPT 1 |
| |
| /* Available ring - see Virtio Spec chapter 2.3.4 */ |
| struct vring_avail { |
| uint16_t flags; |
| uint16_t idx; |
| uint16_t ring[]; |
| }; |
| |
| /* Definitions for vring_used.flags */ |
| #define VRING_USED_F_NO_NOTIFY 1 |
| |
| struct vring_used_elem { |
| uint32_t id; /* Index of start of used descriptor chain */ |
| uint32_t len; /* Total length of the descriptor chain which was used */ |
| }; |
| |
| struct vring_used { |
| uint16_t flags; |
| uint16_t idx; |
| struct vring_used_elem ring[]; |
| }; |
| |
| /* Structure shared with SLOF and is 16bytes */ |
| struct virtio_cap { |
| void *addr; |
| uint8_t bar; |
| uint8_t is_io; |
| uint8_t cap_id; |
| }; |
| |
| struct vqs { |
| uint32_t size; |
| void *buf_mem; |
| struct vring_desc *desc; |
| struct vring_avail *avail; |
| struct vring_used *used; |
| void **desc_gpas; /* to get gpa from desc->addr (which is ioba) */ |
| uint64_t bus_desc; |
| }; |
| |
| struct virtio_device { |
| uint64_t features; |
| struct virtio_cap legacy; |
| struct virtio_cap common; |
| struct virtio_cap notify; |
| struct virtio_cap isr; |
| struct virtio_cap device; |
| struct virtio_cap pci; |
| uint32_t notify_off_mul; |
| struct vqs vq[3]; |
| }; |
| |
| /* Parts of the virtqueue are aligned on a 4096 byte page boundary */ |
| #define VQ_ALIGN(addr) (((addr) + 0xfff) & ~0xfff) |
| |
| extern unsigned long virtio_vring_size(unsigned int qsize); |
| extern unsigned int virtio_get_qsize(struct virtio_device *dev, int queue); |
| extern struct vring_desc *virtio_get_vring_desc(struct virtio_device *dev, int queue); |
| extern struct vring_avail *virtio_get_vring_avail(struct virtio_device *dev, int queue); |
| extern struct vring_used *virtio_get_vring_used(struct virtio_device *dev, int queue); |
| extern void virtio_fill_desc(struct vqs *vq, int id, uint64_t features, |
| uint64_t addr, uint32_t len, |
| uint16_t flags, uint16_t next); |
| extern void virtio_free_desc(struct vqs *vq, int id, uint64_t features); |
| void *virtio_desc_addr(struct virtio_device *vdev, int queue, int id); |
| extern struct vqs *virtio_queue_init_vq(struct virtio_device *dev, unsigned int id); |
| extern void virtio_queue_term_vq(struct virtio_device *dev, struct vqs *vq, unsigned int id); |
| |
| extern struct virtio_device *virtio_setup_vd(void); |
| extern void virtio_reset_device(struct virtio_device *dev); |
| extern void virtio_queue_notify(struct virtio_device *dev, int queue); |
| extern void virtio_set_status(struct virtio_device *dev, int status); |
| extern void virtio_get_status(struct virtio_device *dev, int *status); |
| extern void virtio_set_guest_features(struct virtio_device *dev, uint64_t features); |
| extern uint64_t virtio_get_host_features(struct virtio_device *dev); |
| extern int virtio_negotiate_guest_features(struct virtio_device *dev, uint64_t features); |
| extern uint64_t virtio_get_config(struct virtio_device *dev, int offset, int size); |
| extern int __virtio_read_config(struct virtio_device *dev, void *dst, |
| int offset, int len); |
| |
| |
| #endif /* _LIBVIRTIO_H */ |