xref: /freebsd-src/sys/dev/virtio/virtio.h (revision 180c02405b12e08bbb69bb693a38077db0c85e9b)
1336f459cSPeter Grehan /*-
27282444bSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause
37282444bSPedro F. Giffuni  *
49a732166SBryan Venteicher  * Copyright (c) 2014, Bryan Venteicher <bryanv@FreeBSD.org>
59a732166SBryan Venteicher  * All rights reserved.
610b59a9bSPeter Grehan  *
7336f459cSPeter Grehan  * Redistribution and use in source and binary forms, with or without
8336f459cSPeter Grehan  * modification, are permitted provided that the following conditions
9336f459cSPeter Grehan  * are met:
10336f459cSPeter Grehan  * 1. Redistributions of source code must retain the above copyright
119a732166SBryan Venteicher  *    notice unmodified, this list of conditions, and the following
129a732166SBryan Venteicher  *    disclaimer.
13336f459cSPeter Grehan  * 2. Redistributions in binary form must reproduce the above copyright
14336f459cSPeter Grehan  *    notice, this list of conditions and the following disclaimer in the
15336f459cSPeter Grehan  *    documentation and/or other materials provided with the distribution.
169a732166SBryan Venteicher  *
179a732166SBryan Venteicher  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
189a732166SBryan Venteicher  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
199a732166SBryan Venteicher  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
209a732166SBryan Venteicher  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
219a732166SBryan Venteicher  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
229a732166SBryan Venteicher  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239a732166SBryan Venteicher  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249a732166SBryan Venteicher  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
259a732166SBryan Venteicher  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
269a732166SBryan Venteicher  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2710b59a9bSPeter Grehan  */
2810b59a9bSPeter Grehan 
2910b59a9bSPeter Grehan #ifndef _VIRTIO_H_
3010b59a9bSPeter Grehan #define _VIRTIO_H_
3110b59a9bSPeter Grehan 
329da9560cSBryan Venteicher #include <dev/virtio/virtio_endian.h>
339a732166SBryan Venteicher #include <dev/virtio/virtio_ids.h>
3445543f07SBryan Venteicher #include <dev/virtio/virtio_config.h>
359a732166SBryan Venteicher 
3654ac6f72SKa Ho Ng #ifdef _KERNEL
3754ac6f72SKa Ho Ng 
38703f17d6SBryan Venteicher struct sbuf;
3910b59a9bSPeter Grehan struct vq_alloc_info;
4010b59a9bSPeter Grehan 
4110b59a9bSPeter Grehan /*
4210b59a9bSPeter Grehan  * Each virtqueue indirect descriptor list must be physically contiguous.
4310b59a9bSPeter Grehan  * To allow us to malloc(9) each list individually, limit the number
4410b59a9bSPeter Grehan  * supported to what will fit in one page. With 4KB pages, this is a limit
4510b59a9bSPeter Grehan  * of 256 descriptors. If there is ever a need for more, we can switch to
4610b59a9bSPeter Grehan  * contigmalloc(9) for the larger allocations, similar to what
4710b59a9bSPeter Grehan  * bus_dmamem_alloc(9) does.
4810b59a9bSPeter Grehan  *
4910b59a9bSPeter Grehan  * Note the sizeof(struct vring_desc) is 16 bytes.
5010b59a9bSPeter Grehan  */
5110b59a9bSPeter Grehan #define VIRTIO_MAX_INDIRECT ((int) (PAGE_SIZE / 16))
5210b59a9bSPeter Grehan 
5310b59a9bSPeter Grehan /*
5410b59a9bSPeter Grehan  * VirtIO instance variables indices.
5510b59a9bSPeter Grehan  */
5610b59a9bSPeter Grehan #define VIRTIO_IVAR_DEVTYPE		1
5710b59a9bSPeter Grehan #define VIRTIO_IVAR_FEATURE_DESC	2
58310dacd0SPeter Grehan #define VIRTIO_IVAR_VENDOR		3
59310dacd0SPeter Grehan #define VIRTIO_IVAR_DEVICE		4
60310dacd0SPeter Grehan #define VIRTIO_IVAR_SUBVENDOR		5
61310dacd0SPeter Grehan #define VIRTIO_IVAR_SUBDEVICE		6
629da9560cSBryan Venteicher #define VIRTIO_IVAR_MODERN		7
6310b59a9bSPeter Grehan 
6410b59a9bSPeter Grehan struct virtio_feature_desc {
6510b59a9bSPeter Grehan 	uint64_t	 vfd_val;
66abd6790cSBryan Venteicher 	const char	*vfd_str;
6710b59a9bSPeter Grehan };
6810b59a9bSPeter Grehan 
695c4c96d3SJohn Baldwin #define VIRTIO_DRIVER_MODULE(name, driver, evh, arg)			\
705c4c96d3SJohn Baldwin 	DRIVER_MODULE(name, virtio_mmio, driver, evh, arg);		\
715c4c96d3SJohn Baldwin 	DRIVER_MODULE(name, virtio_pci, driver, evh, arg)
72633218eeSJessica Clarke 
730f6040f0SConrad Meyer struct virtio_pnp_match {
740f6040f0SConrad Meyer 	uint32_t	 device_type;
750f6040f0SConrad Meyer 	const char	*description;
760f6040f0SConrad Meyer };
77633218eeSJessica Clarke #define VIRTIO_SIMPLE_PNPINFO(driver, devtype, desc)			\
780f6040f0SConrad Meyer 	static const struct virtio_pnp_match driver ## _match = {	\
790f6040f0SConrad Meyer 		.device_type = devtype,					\
800f6040f0SConrad Meyer 		.description = desc,					\
81633218eeSJessica Clarke 	};								\
82633218eeSJessica Clarke 	MODULE_PNP_INFO("U32:device_type;D:#", virtio_mmio, driver,	\
83633218eeSJessica Clarke 	    &driver ## _match, 1);					\
84633218eeSJessica Clarke 	MODULE_PNP_INFO("U32:device_type;D:#", virtio_pci, driver,	\
850f6040f0SConrad Meyer 	    &driver ## _match, 1)
860f6040f0SConrad Meyer #define VIRTIO_SIMPLE_PROBE(dev, driver)				\
870f6040f0SConrad Meyer 	(virtio_simple_probe(dev, &driver ## _match))
880f6040f0SConrad Meyer 
8910b59a9bSPeter Grehan const char *virtio_device_name(uint16_t devid);
9010b59a9bSPeter Grehan void	 virtio_describe(device_t dev, const char *msg,
91703f17d6SBryan Venteicher 	     uint64_t features, struct virtio_feature_desc *desc);
92703f17d6SBryan Venteicher int	 virtio_describe_sbuf(struct sbuf *sb, uint64_t features,
93703f17d6SBryan Venteicher 	     struct virtio_feature_desc *desc);
949da9560cSBryan Venteicher uint64_t virtio_filter_transport_features(uint64_t features);
95ccb576a8SMina Galić bool	 virtio_bus_is_modern(device_t dev);
969da9560cSBryan Venteicher void	 virtio_read_device_config_array(device_t dev, bus_size_t offset,
979da9560cSBryan Venteicher 	     void *dst, int size, int count);
9810b59a9bSPeter Grehan 
9910b59a9bSPeter Grehan /*
10010b59a9bSPeter Grehan  * VirtIO Bus Methods.
10110b59a9bSPeter Grehan  */
102310dacd0SPeter Grehan void	 virtio_read_ivar(device_t dev, int ivar, uintptr_t *val);
103310dacd0SPeter Grehan void	 virtio_write_ivar(device_t dev, int ivar, uintptr_t val);
10410b59a9bSPeter Grehan uint64_t virtio_negotiate_features(device_t dev, uint64_t child_features);
1059da9560cSBryan Venteicher int	 virtio_finalize_features(device_t dev);
106*180c0240SMina Galić int	 virtio_alloc_virtqueues(device_t dev, int nvqs,
10710b59a9bSPeter Grehan 	     struct vq_alloc_info *info);
10810b59a9bSPeter Grehan int	 virtio_setup_intr(device_t dev, enum intr_type type);
109ccb576a8SMina Galić bool	 virtio_with_feature(device_t dev, uint64_t feature);
11010b59a9bSPeter Grehan void	 virtio_stop(device_t dev);
111985ed053SBryan Venteicher int	 virtio_config_generation(device_t dev);
11210b59a9bSPeter Grehan int	 virtio_reinit(device_t dev, uint64_t features);
11310b59a9bSPeter Grehan void	 virtio_reinit_complete(device_t dev);
114ddfc9c4cSWarner Losh int	 virtio_child_pnpinfo(device_t busdev, device_t child, struct sbuf *sb);
11510b59a9bSPeter Grehan 
11610b59a9bSPeter Grehan /*
11710b59a9bSPeter Grehan  * Read/write a variable amount from the device specific (ie, network)
11810b59a9bSPeter Grehan  * configuration region. This region is encoded in the same endian as
11910b59a9bSPeter Grehan  * the guest.
12010b59a9bSPeter Grehan  */
12110b59a9bSPeter Grehan void	 virtio_read_device_config(device_t dev, bus_size_t offset,
12210b59a9bSPeter Grehan 	     void *dst, int length);
12310b59a9bSPeter Grehan void	 virtio_write_device_config(device_t dev, bus_size_t offset,
1246c4f9516SAlex Richardson 	     const void *src, int length);
12510b59a9bSPeter Grehan 
12610b59a9bSPeter Grehan /* Inlined device specific read/write functions for common lengths. */
12710b59a9bSPeter Grehan #define VIRTIO_RDWR_DEVICE_CONFIG(size, type)				\
12810b59a9bSPeter Grehan static inline type							\
12910b59a9bSPeter Grehan __CONCAT(virtio_read_dev_config_,size)(device_t dev,			\
13010b59a9bSPeter Grehan     bus_size_t offset)							\
13110b59a9bSPeter Grehan {									\
13210b59a9bSPeter Grehan 	type val;							\
13310b59a9bSPeter Grehan 	virtio_read_device_config(dev, offset, &val, sizeof(type));	\
13410b59a9bSPeter Grehan 	return (val);							\
13510b59a9bSPeter Grehan }									\
13610b59a9bSPeter Grehan 									\
13710b59a9bSPeter Grehan static inline void							\
13810b59a9bSPeter Grehan __CONCAT(virtio_write_dev_config_,size)(device_t dev,			\
13910b59a9bSPeter Grehan     bus_size_t offset, type val)					\
14010b59a9bSPeter Grehan {									\
14110b59a9bSPeter Grehan 	virtio_write_device_config(dev, offset, &val, sizeof(type));	\
14210b59a9bSPeter Grehan }
14310b59a9bSPeter Grehan 
14410b59a9bSPeter Grehan VIRTIO_RDWR_DEVICE_CONFIG(1, uint8_t);
14510b59a9bSPeter Grehan VIRTIO_RDWR_DEVICE_CONFIG(2, uint16_t);
14610b59a9bSPeter Grehan VIRTIO_RDWR_DEVICE_CONFIG(4, uint32_t);
14710b59a9bSPeter Grehan 
14860ff3342SPeter Grehan #undef VIRTIO_RDWR_DEVICE_CONFIG
14960ff3342SPeter Grehan 
150310dacd0SPeter Grehan #define VIRTIO_READ_IVAR(name, ivar)					\
151310dacd0SPeter Grehan static inline int							\
152310dacd0SPeter Grehan __CONCAT(virtio_get_,name)(device_t dev)				\
153310dacd0SPeter Grehan {									\
154310dacd0SPeter Grehan 	uintptr_t val;							\
155310dacd0SPeter Grehan 	virtio_read_ivar(dev, ivar, &val);				\
156310dacd0SPeter Grehan 	return ((int) val);						\
157310dacd0SPeter Grehan }
158310dacd0SPeter Grehan 
159310dacd0SPeter Grehan VIRTIO_READ_IVAR(device_type,	VIRTIO_IVAR_DEVTYPE);
160310dacd0SPeter Grehan VIRTIO_READ_IVAR(vendor,	VIRTIO_IVAR_VENDOR);
161310dacd0SPeter Grehan VIRTIO_READ_IVAR(device,	VIRTIO_IVAR_DEVICE);
162310dacd0SPeter Grehan VIRTIO_READ_IVAR(subvendor,	VIRTIO_IVAR_SUBVENDOR);
163310dacd0SPeter Grehan VIRTIO_READ_IVAR(subdevice,	VIRTIO_IVAR_SUBDEVICE);
1649da9560cSBryan Venteicher VIRTIO_READ_IVAR(modern,	VIRTIO_IVAR_MODERN);
165310dacd0SPeter Grehan 
16660ff3342SPeter Grehan #undef VIRTIO_READ_IVAR
16760ff3342SPeter Grehan 
168310dacd0SPeter Grehan #define VIRTIO_WRITE_IVAR(name, ivar)					\
169310dacd0SPeter Grehan static inline void							\
170310dacd0SPeter Grehan __CONCAT(virtio_set_,name)(device_t dev, void *val)			\
171310dacd0SPeter Grehan {									\
172310dacd0SPeter Grehan 	virtio_write_ivar(dev, ivar, (uintptr_t) val);			\
173310dacd0SPeter Grehan }
174310dacd0SPeter Grehan 
175310dacd0SPeter Grehan VIRTIO_WRITE_IVAR(feature_desc,	VIRTIO_IVAR_FEATURE_DESC);
176310dacd0SPeter Grehan 
17760ff3342SPeter Grehan #undef VIRTIO_WRITE_IVAR
17860ff3342SPeter Grehan 
1790f6040f0SConrad Meyer static inline int
virtio_simple_probe(device_t dev,const struct virtio_pnp_match * match)1800f6040f0SConrad Meyer virtio_simple_probe(device_t dev, const struct virtio_pnp_match *match)
1810f6040f0SConrad Meyer {
1820f6040f0SConrad Meyer 
1830f6040f0SConrad Meyer 	if (virtio_get_device_type(dev) != match->device_type)
1840f6040f0SConrad Meyer 		return (ENXIO);
1850f6040f0SConrad Meyer 	device_set_desc(dev, match->description);
1860f6040f0SConrad Meyer 	return (BUS_PROBE_DEFAULT);
1870f6040f0SConrad Meyer }
1880f6040f0SConrad Meyer 
18954ac6f72SKa Ho Ng #endif /* _KERNEL */
19054ac6f72SKa Ho Ng 
19110b59a9bSPeter Grehan #endif /* _VIRTIO_H_ */
192