1 /*
2  * Copyright (c) 2022 Wind River Systems, Inc.
3  * Based on Virtio PCI driver by Anthony Liguori, copyright IBM Corp. 2007
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef OPENAMP_VIRTIO_MMIO_H
9 #define OPENAMP_VIRTIO_MMIO_H
10 
11 #include <metal/device.h>
12 #include <openamp/virtio.h>
13 #include <openamp/virtqueue.h>
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /* Enable support for legacy devices */
20 #define VIRTIO_MMIO_LEGACY
21 
22 /* Control registers */
23 
24 /* Magic value ("virt" string) - Read Only */
25 #define VIRTIO_MMIO_MAGIC_VALUE		0x000
26 
27 #define VIRTIO_MMIO_MAGIC_VALUE_STRING ('v' | ('i' << 8) | ('r' << 16) | ('t' << 24))
28 
29 /* Virtio device version - Read Only */
30 #define VIRTIO_MMIO_VERSION		0x004
31 
32 /* Virtio device ID - Read Only */
33 #define VIRTIO_MMIO_DEVICE_ID		0x008
34 
35 /* Virtio vendor ID - Read Only */
36 #define VIRTIO_MMIO_VENDOR_ID		0x00c
37 
38 /*
39  * Bitmask of the features supported by the device (host)
40  * (32 bits per set) - Read Only
41  */
42 #define VIRTIO_MMIO_DEVICE_FEATURES	0x010
43 
44 /* Device (host) features set selector - Write Only */
45 #define VIRTIO_MMIO_DEVICE_FEATURES_SEL	0x014
46 
47 /*
48  * Bitmask of features activated by the driver (guest)
49  * (32 bits per set) - Write Only
50  */
51 #define VIRTIO_MMIO_DRIVER_FEATURES	0x020
52 
53 /* Activated features set selector - Write Only */
54 #define VIRTIO_MMIO_DRIVER_FEATURES_SEL	0x024
55 
56 #ifndef VIRTIO_MMIO_NO_LEGACY /* LEGACY DEVICES ONLY! */
57 /* Guest's memory page size in bytes - Write Only */
58 #define VIRTIO_MMIO_GUEST_PAGE_SIZE	0x028
59 #endif
60 
61 /* Queue selector - Write Only */
62 #define VIRTIO_MMIO_QUEUE_SEL		0x030
63 
64 /* Maximum size of the currently selected queue - Read Only */
65 #define VIRTIO_MMIO_QUEUE_NUM_MAX	0x034
66 
67 /* Queue size for the currently selected queue - Write Only */
68 #define VIRTIO_MMIO_QUEUE_NUM		0x038
69 
70 #ifdef VIRTIO_MMIO_LEGACY
71 /* Used Ring alignment for the currently selected queue - Write Only */
72 #define VIRTIO_MMIO_QUEUE_ALIGN		0x03c
73 /* Guest's PFN for the currently selected queue - Read Write */
74 #define VIRTIO_MMIO_QUEUE_PFN		0x040
75 #endif
76 
77 /* Ready bit for the currently selected queue - Read Write */
78 #define VIRTIO_MMIO_QUEUE_READY		0x044
79 
80 /* Queue notifier - Write Only */
81 #define VIRTIO_MMIO_QUEUE_NOTIFY	0x050
82 
83 /* Interrupt status - Read Only */
84 #define VIRTIO_MMIO_INTERRUPT_STATUS	0x060
85 
86 /* Interrupt acknowledge - Write Only */
87 #define VIRTIO_MMIO_INTERRUPT_ACK	0x064
88 
89 /* Device status register - Read Write */
90 #define VIRTIO_MMIO_STATUS		0x070
91 
92 /* Selected queue's Descriptor Table address, 64 bits in two halves */
93 #define VIRTIO_MMIO_QUEUE_DESC_LOW	0x080
94 #define VIRTIO_MMIO_QUEUE_DESC_HIGH	0x084
95 
96 /* Selected queue's Available Ring address, 64 bits in two halves */
97 #define VIRTIO_MMIO_QUEUE_AVAIL_LOW	0x090
98 #define VIRTIO_MMIO_QUEUE_AVAIL_HIGH	0x094
99 
100 /* Selected queue's Used Ring address, 64 bits in two halves */
101 #define VIRTIO_MMIO_QUEUE_USED_LOW	0x0a0
102 #define VIRTIO_MMIO_QUEUE_USED_HIGH	0x0a4
103 
104 /* Shared memory region id */
105 #define VIRTIO_MMIO_SHM_SEL             0x0ac
106 
107 /* Shared memory region length, 64 bits in two halves */
108 #define VIRTIO_MMIO_SHM_LEN_LOW         0x0b0
109 #define VIRTIO_MMIO_SHM_LEN_HIGH        0x0b4
110 
111 /* Shared memory region base address, 64 bits in two halves */
112 #define VIRTIO_MMIO_SHM_BASE_LOW        0x0b8
113 #define VIRTIO_MMIO_SHM_BASE_HIGH       0x0bc
114 
115 /* Configuration atomicity value */
116 #define VIRTIO_MMIO_CONFIG_GENERATION	0x0fc
117 
118 /*
119  * The config space is defined by each driver as
120  * the per-driver configuration space - Read Write
121  */
122 #define VIRTIO_MMIO_CONFIG		0x100
123 
124 /* Interrupt flags (re: interrupt status & acknowledge registers) */
125 #define VIRTIO_MMIO_INT_VRING		(1 << 0)
126 #define VIRTIO_MMIO_INT_CONFIG		(1 << 1)
127 
128 /* Data buffer size for preallocated buffers before vring */
129 #define VIRTIO_MMIO_MAX_DATA_SIZE 128
130 
131 /** @brief VIRTIO MMIO memory area */
132 struct virtio_mmio_dev_mem {
133 	/** Memory region physical address */
134 	void *base;
135 
136 	/** Memory region size */
137 	size_t size;
138 };
139 
140 /** @brief A VIRTIO MMIO device */
141 struct virtio_mmio_device {
142 	/** Base virtio device structure */
143 	struct virtio_device vdev;
144 
145 	/** Device configuration space metal_io_region */
146 	struct metal_io_region cfg_io;
147 
148 	/** Pre-shared memory space metal_io_region */
149 	struct metal_io_region shm_io;
150 
151 	/** VIRTIO device configuration space */
152 	struct virtio_mmio_dev_mem cfg_mem;
153 
154 	/** VIRTIO device pre-shared memory */
155 	struct virtio_mmio_dev_mem shm_mem;
156 
157 	/** VIRTIO_DEV_DRIVER or VIRTIO_DEV_DEVICE */
158 	unsigned int device_mode;
159 
160 	/** Interrupt number */
161 	unsigned int irq;
162 
163 	/** Custom user data */
164 	void *user_data;
165 };
166 
167 /**
168  * @brief Register a VIRTIO device with the VIRTIO stack.
169  *
170  * @param vdev		Pointer to device structure.
171  * @param vq_num	Number of virtqueues the device uses.
172  * @param vqs		Array of pointers to vthe virtqueues used by the device.
173  */
174 void virtio_mmio_register_device(struct virtio_device *vdev, int vq_num, struct virtqueue **vqs);
175 
176 /**
177  * @brief Setup a virtqueue structure.
178  *
179  * @param vdev		Pointer to device structure.
180  * @param idx		Index of the virtqueue.
181  * @param vq		Pointer to virtqueue structure.
182  * @param cb		Pointer to virtqueue callback. Can be NULL.
183  * @param cb_arg	Argument for the virtqueue callback.
184  * @param vq_name	Name of the virtqueue.
185  *
186  * @return pointer to virtqueue structure.
187  */
188 struct virtqueue *virtio_mmio_setup_virtqueue(struct virtio_device *vdev,
189 					      unsigned int idx,
190 					      struct virtqueue *vq,
191 					      void (*cb)(void *),
192 					      void *cb_arg,
193 					      const char *vq_name);
194 
195 /**
196  * @brief VIRTIO MMIO device initialization.
197  *
198  * @param vmdev		Pointer to virtio_mmio_device structure.
199  * @param virt_mem_ptr	Guest virtio (shared) memory base address (virtual).
200  * @param cfg_mem_ptr	Virtio device configuration memory base address (virtual).
201  * @param user_data	Pointer to custom user data.
202  *
203  * @return int 0 for success.
204  */
205 int virtio_mmio_device_init(struct virtio_mmio_device *vmdev, uintptr_t virt_mem_ptr,
206 			    uintptr_t cfg_mem_ptr, void *user_data);
207 
208 /**
209  * @brief VIRTIO MMIO interrupt service routine.
210  *
211  * @param vdev Pointer to virtio_device structure.
212  */
213 void virtio_mmio_isr(struct virtio_device *vdev);
214 
215 #ifdef __cplusplus
216 }
217 #endif
218 
219 #endif /* OPENAMP_VIRTIO_MMIO_H */
220