xref: /kvm-unit-tests/lib/virtio-mmio.h (revision 49f758b8a983e49b4537ea2726e8a83a0d5632ad)
143402ba5SAndrew Jones #ifndef _VIRTIO_MMIO_H_
243402ba5SAndrew Jones #define _VIRTIO_MMIO_H_
343402ba5SAndrew Jones /*
443402ba5SAndrew Jones  * A minimal implementation of virtio-mmio. Adapted from the Linux Kernel.
543402ba5SAndrew Jones  *
6*49f758b8SAndrew Jones  * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com>
743402ba5SAndrew Jones  *
8*49f758b8SAndrew Jones  * This work is licensed under the terms of the GNU GPL, version 2.
943402ba5SAndrew Jones  */
1043402ba5SAndrew Jones #include "libcflat.h"
11d73e4521SAndrew Jones #include "asm/page.h"
1243402ba5SAndrew Jones #include "virtio.h"
1343402ba5SAndrew Jones 
1443402ba5SAndrew Jones #define VIRTIO_MMIO_MAGIC_VALUE		0x000
1543402ba5SAndrew Jones #define VIRTIO_MMIO_VERSION		0x004
1643402ba5SAndrew Jones #define VIRTIO_MMIO_DEVICE_ID		0x008
1743402ba5SAndrew Jones #define VIRTIO_MMIO_VENDOR_ID		0x00c
1843402ba5SAndrew Jones #define VIRTIO_MMIO_HOST_FEATURES	0x010
1943402ba5SAndrew Jones #define VIRTIO_MMIO_HOST_FEATURES_SEL	0x014
2043402ba5SAndrew Jones #define VIRTIO_MMIO_GUEST_FEATURES	0x020
2143402ba5SAndrew Jones #define VIRTIO_MMIO_GUEST_FEATURES_SEL	0x024
2243402ba5SAndrew Jones #define VIRTIO_MMIO_GUEST_PAGE_SIZE	0x028
2343402ba5SAndrew Jones #define VIRTIO_MMIO_QUEUE_SEL		0x030
2443402ba5SAndrew Jones #define VIRTIO_MMIO_QUEUE_NUM_MAX	0x034
2543402ba5SAndrew Jones #define VIRTIO_MMIO_QUEUE_NUM		0x038
2643402ba5SAndrew Jones #define VIRTIO_MMIO_QUEUE_ALIGN		0x03c
2743402ba5SAndrew Jones #define VIRTIO_MMIO_QUEUE_PFN		0x040
2843402ba5SAndrew Jones #define VIRTIO_MMIO_QUEUE_NOTIFY	0x050
2943402ba5SAndrew Jones #define VIRTIO_MMIO_INTERRUPT_STATUS	0x060
3043402ba5SAndrew Jones #define VIRTIO_MMIO_INTERRUPT_ACK	0x064
3143402ba5SAndrew Jones #define VIRTIO_MMIO_STATUS		0x070
3243402ba5SAndrew Jones #define VIRTIO_MMIO_CONFIG		0x100
3343402ba5SAndrew Jones 
3443402ba5SAndrew Jones #define VIRTIO_MMIO_INT_VRING		(1 << 0)
3543402ba5SAndrew Jones #define VIRTIO_MMIO_INT_CONFIG		(1 << 1)
3643402ba5SAndrew Jones 
37d73e4521SAndrew Jones #define VIRTIO_MMIO_VRING_ALIGN		PAGE_SIZE
38d73e4521SAndrew Jones 
39d73e4521SAndrew Jones /*
40d73e4521SAndrew Jones  * The minimum queue size is 2*VIRTIO_MMIO_VRING_ALIGN, which
41d73e4521SAndrew Jones  * means the largest queue num for the minimum queue size is 128, i.e.
42d73e4521SAndrew Jones  * 2*VIRTIO_MMIO_VRING_ALIGN = vring_size(128, VIRTIO_MMIO_VRING_ALIGN),
43d73e4521SAndrew Jones  * where vring_size is
44d73e4521SAndrew Jones  *
45d73e4521SAndrew Jones  * unsigned vring_size(unsigned num, unsigned long align)
46d73e4521SAndrew Jones  * {
47d73e4521SAndrew Jones  *     return ((sizeof(struct vring_desc) * num + sizeof(u16) * (3 + num)
48d73e4521SAndrew Jones  *              + align - 1) & ~(align - 1))
49d73e4521SAndrew Jones  *             + sizeof(u16) * 3 + sizeof(struct vring_used_elem) * num;
50d73e4521SAndrew Jones  * }
51d73e4521SAndrew Jones  */
52d73e4521SAndrew Jones #define VIRTIO_MMIO_QUEUE_SIZE_MIN	(2*VIRTIO_MMIO_VRING_ALIGN)
53d73e4521SAndrew Jones #define VIRTIO_MMIO_QUEUE_NUM_MIN	128
5443402ba5SAndrew Jones 
5543402ba5SAndrew Jones #define to_virtio_mmio_device(vdev_ptr) \
5643402ba5SAndrew Jones 	container_of(vdev_ptr, struct virtio_mmio_device, vdev)
5743402ba5SAndrew Jones 
5843402ba5SAndrew Jones struct virtio_mmio_device {
5943402ba5SAndrew Jones 	struct virtio_device vdev;
6043402ba5SAndrew Jones 	void *base;
6143402ba5SAndrew Jones };
6243402ba5SAndrew Jones 
6343402ba5SAndrew Jones extern struct virtio_device *virtio_mmio_bind(u32 devid);
6443402ba5SAndrew Jones 
6543402ba5SAndrew Jones #endif /* _VIRTIO_MMIO_H_ */
66