1 #ifndef _VIRTIO_MMIO_H_ 2 #define _VIRTIO_MMIO_H_ 3 /* 4 * A minimal implementation of virtio-mmio. Adapted from the Linux Kernel. 5 * 6 * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com> 7 * 8 * This work is licensed under the terms of the GNU GPL, version 2. 9 */ 10 #include "libcflat.h" 11 #include "asm/page.h" 12 #include "virtio.h" 13 14 #define VIRTIO_MMIO_MAGIC_VALUE 0x000 15 #define VIRTIO_MMIO_VERSION 0x004 16 #define VIRTIO_MMIO_DEVICE_ID 0x008 17 #define VIRTIO_MMIO_VENDOR_ID 0x00c 18 #define VIRTIO_MMIO_HOST_FEATURES 0x010 19 #define VIRTIO_MMIO_HOST_FEATURES_SEL 0x014 20 #define VIRTIO_MMIO_GUEST_FEATURES 0x020 21 #define VIRTIO_MMIO_GUEST_FEATURES_SEL 0x024 22 #define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028 23 #define VIRTIO_MMIO_QUEUE_SEL 0x030 24 #define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034 25 #define VIRTIO_MMIO_QUEUE_NUM 0x038 26 #define VIRTIO_MMIO_QUEUE_ALIGN 0x03c 27 #define VIRTIO_MMIO_QUEUE_PFN 0x040 28 #define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 29 #define VIRTIO_MMIO_INTERRUPT_STATUS 0x060 30 #define VIRTIO_MMIO_INTERRUPT_ACK 0x064 31 #define VIRTIO_MMIO_STATUS 0x070 32 #define VIRTIO_MMIO_CONFIG 0x100 33 34 #define VIRTIO_MMIO_INT_VRING (1 << 0) 35 #define VIRTIO_MMIO_INT_CONFIG (1 << 1) 36 37 #define VIRTIO_MMIO_VRING_ALIGN PAGE_SIZE 38 39 /* 40 * The minimum queue size is 2*VIRTIO_MMIO_VRING_ALIGN, which 41 * means the largest queue num for the minimum queue size is 128, i.e. 42 * 2*VIRTIO_MMIO_VRING_ALIGN = vring_size(128, VIRTIO_MMIO_VRING_ALIGN), 43 * where vring_size is 44 * 45 * unsigned vring_size(unsigned num, unsigned long align) 46 * { 47 * return ((sizeof(struct vring_desc) * num + sizeof(u16) * (3 + num) 48 * + align - 1) & ~(align - 1)) 49 * + sizeof(u16) * 3 + sizeof(struct vring_used_elem) * num; 50 * } 51 */ 52 #define VIRTIO_MMIO_QUEUE_SIZE_MIN (2*VIRTIO_MMIO_VRING_ALIGN) 53 #define VIRTIO_MMIO_QUEUE_NUM_MIN 128 54 55 #define to_virtio_mmio_device(vdev_ptr) \ 56 container_of(vdev_ptr, struct virtio_mmio_device, vdev) 57 58 struct virtio_mmio_device { 59 struct virtio_device vdev; 60 void *base; 61 }; 62 63 extern struct virtio_device *virtio_mmio_bind(u32 devid); 64 65 #endif /* _VIRTIO_MMIO_H_ */ 66