1228301Sgrehan/*- 2267312Sbryanv * Copyright (c) 2014, Bryan Venteicher <bryanv@FreeBSD.org> 3267312Sbryanv * All rights reserved. 4227652Sgrehan * 5228301Sgrehan * Redistribution and use in source and binary forms, with or without 6228301Sgrehan * modification, are permitted provided that the following conditions 7228301Sgrehan * are met: 8228301Sgrehan * 1. Redistributions of source code must retain the above copyright 9267312Sbryanv * notice unmodified, this list of conditions, and the following 10267312Sbryanv * disclaimer. 11228301Sgrehan * 2. Redistributions in binary form must reproduce the above copyright 12228301Sgrehan * notice, this list of conditions and the following disclaimer in the 13228301Sgrehan * documentation and/or other materials provided with the distribution. 14228301Sgrehan * 15267312Sbryanv * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16267312Sbryanv * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17267312Sbryanv * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18267312Sbryanv * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19267312Sbryanv * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20267312Sbryanv * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21267312Sbryanv * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22267312Sbryanv * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23267312Sbryanv * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24267312Sbryanv * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25267312Sbryanv * 26227652Sgrehan * $FreeBSD$ 27227652Sgrehan */ 28227652Sgrehan 29227652Sgrehan#ifndef _VIRTIO_H_ 30227652Sgrehan#define _VIRTIO_H_ 31227652Sgrehan 32267312Sbryanv#include <dev/virtio/virtio_ids.h> 33268010Sbryanv#include <dev/virtio/virtio_config.h> 34267312Sbryanv 35227652Sgrehanstruct vq_alloc_info; 36227652Sgrehan 37227652Sgrehan/* 38227652Sgrehan * Each virtqueue indirect descriptor list must be physically contiguous. 39227652Sgrehan * To allow us to malloc(9) each list individually, limit the number 40227652Sgrehan * supported to what will fit in one page. With 4KB pages, this is a limit 41227652Sgrehan * of 256 descriptors. If there is ever a need for more, we can switch to 42227652Sgrehan * contigmalloc(9) for the larger allocations, similar to what 43227652Sgrehan * bus_dmamem_alloc(9) does. 44227652Sgrehan * 45227652Sgrehan * Note the sizeof(struct vring_desc) is 16 bytes. 46227652Sgrehan */ 47227652Sgrehan#define VIRTIO_MAX_INDIRECT ((int) (PAGE_SIZE / 16)) 48227652Sgrehan 49227652Sgrehan/* 50227652Sgrehan * VirtIO instance variables indices. 51227652Sgrehan */ 52227652Sgrehan#define VIRTIO_IVAR_DEVTYPE 1 53227652Sgrehan#define VIRTIO_IVAR_FEATURE_DESC 2 54238360Sgrehan#define VIRTIO_IVAR_VENDOR 3 55238360Sgrehan#define VIRTIO_IVAR_DEVICE 4 56238360Sgrehan#define VIRTIO_IVAR_SUBVENDOR 5 57238360Sgrehan#define VIRTIO_IVAR_SUBDEVICE 6 58227652Sgrehan 59227652Sgrehanstruct virtio_feature_desc { 60227652Sgrehan uint64_t vfd_val; 61252707Sbryanv const char *vfd_str; 62227652Sgrehan}; 63227652Sgrehan 64227652Sgrehanconst char *virtio_device_name(uint16_t devid); 65227652Sgrehanvoid virtio_describe(device_t dev, const char *msg, 66227652Sgrehan uint64_t features, struct virtio_feature_desc *feature_desc); 67227652Sgrehan 68227652Sgrehan/* 69227652Sgrehan * VirtIO Bus Methods. 70227652Sgrehan */ 71238360Sgrehanvoid virtio_read_ivar(device_t dev, int ivar, uintptr_t *val); 72238360Sgrehanvoid virtio_write_ivar(device_t dev, int ivar, uintptr_t val); 73227652Sgrehanuint64_t virtio_negotiate_features(device_t dev, uint64_t child_features); 74227652Sgrehanint virtio_alloc_virtqueues(device_t dev, int flags, int nvqs, 75227652Sgrehan struct vq_alloc_info *info); 76227652Sgrehanint virtio_setup_intr(device_t dev, enum intr_type type); 77227652Sgrehanint virtio_with_feature(device_t dev, uint64_t feature); 78227652Sgrehanvoid virtio_stop(device_t dev); 79227652Sgrehanint virtio_reinit(device_t dev, uint64_t features); 80227652Sgrehanvoid virtio_reinit_complete(device_t dev); 81227652Sgrehan 82227652Sgrehan/* 83227652Sgrehan * Read/write a variable amount from the device specific (ie, network) 84227652Sgrehan * configuration region. This region is encoded in the same endian as 85227652Sgrehan * the guest. 86227652Sgrehan */ 87227652Sgrehanvoid virtio_read_device_config(device_t dev, bus_size_t offset, 88227652Sgrehan void *dst, int length); 89227652Sgrehanvoid virtio_write_device_config(device_t dev, bus_size_t offset, 90227652Sgrehan void *src, int length); 91227652Sgrehan 92227652Sgrehan/* Inlined device specific read/write functions for common lengths. */ 93227652Sgrehan#define VIRTIO_RDWR_DEVICE_CONFIG(size, type) \ 94227652Sgrehanstatic inline type \ 95227652Sgrehan__CONCAT(virtio_read_dev_config_,size)(device_t dev, \ 96227652Sgrehan bus_size_t offset) \ 97227652Sgrehan{ \ 98227652Sgrehan type val; \ 99227652Sgrehan virtio_read_device_config(dev, offset, &val, sizeof(type)); \ 100227652Sgrehan return (val); \ 101227652Sgrehan} \ 102227652Sgrehan \ 103227652Sgrehanstatic inline void \ 104227652Sgrehan__CONCAT(virtio_write_dev_config_,size)(device_t dev, \ 105227652Sgrehan bus_size_t offset, type val) \ 106227652Sgrehan{ \ 107227652Sgrehan virtio_write_device_config(dev, offset, &val, sizeof(type)); \ 108227652Sgrehan} 109227652Sgrehan 110227652SgrehanVIRTIO_RDWR_DEVICE_CONFIG(1, uint8_t); 111227652SgrehanVIRTIO_RDWR_DEVICE_CONFIG(2, uint16_t); 112227652SgrehanVIRTIO_RDWR_DEVICE_CONFIG(4, uint32_t); 113227652Sgrehan 114240430Sgrehan#undef VIRTIO_RDWR_DEVICE_CONFIG 115240430Sgrehan 116238360Sgrehan#define VIRTIO_READ_IVAR(name, ivar) \ 117238360Sgrehanstatic inline int \ 118238360Sgrehan__CONCAT(virtio_get_,name)(device_t dev) \ 119238360Sgrehan{ \ 120238360Sgrehan uintptr_t val; \ 121238360Sgrehan virtio_read_ivar(dev, ivar, &val); \ 122238360Sgrehan return ((int) val); \ 123238360Sgrehan} 124238360Sgrehan 125238360SgrehanVIRTIO_READ_IVAR(device_type, VIRTIO_IVAR_DEVTYPE); 126238360SgrehanVIRTIO_READ_IVAR(vendor, VIRTIO_IVAR_VENDOR); 127238360SgrehanVIRTIO_READ_IVAR(device, VIRTIO_IVAR_DEVICE); 128238360SgrehanVIRTIO_READ_IVAR(subvendor, VIRTIO_IVAR_SUBVENDOR); 129238360SgrehanVIRTIO_READ_IVAR(subdevice, VIRTIO_IVAR_SUBDEVICE); 130238360Sgrehan 131240430Sgrehan#undef VIRTIO_READ_IVAR 132240430Sgrehan 133238360Sgrehan#define VIRTIO_WRITE_IVAR(name, ivar) \ 134238360Sgrehanstatic inline void \ 135238360Sgrehan__CONCAT(virtio_set_,name)(device_t dev, void *val) \ 136238360Sgrehan{ \ 137238360Sgrehan virtio_write_ivar(dev, ivar, (uintptr_t) val); \ 138238360Sgrehan} 139238360Sgrehan 140238360SgrehanVIRTIO_WRITE_IVAR(feature_desc, VIRTIO_IVAR_FEATURE_DESC); 141238360Sgrehan 142240430Sgrehan#undef VIRTIO_WRITE_IVAR 143240430Sgrehan 144227652Sgrehan#endif /* _VIRTIO_H_ */ 145