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