xref: /freebsd/sys/dev/hyperv/vmbus/vmbus_reg.h (revision e32fecd0c2c3ee37c47ee100f169e7eb0282a873)
1 /*-
2  * Copyright (c) 2016 Microsoft Corp.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice unmodified, this list of conditions, and the following
10  *    disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 #ifndef _VMBUS_REG_H_
30 #define _VMBUS_REG_H_
31 
32 #include <sys/param.h>
33 #include <dev/hyperv/include/hyperv.h> /* XXX for hyperv_guid */
34 #include <dev/hyperv/include/vmbus.h>
35 #if defined(__aarch64__)
36 #include <dev/hyperv/vmbus/aarch64/hyperv_reg.h>
37 #else
38 #include <dev/hyperv/vmbus/x86/hyperv_reg.h>
39 #endif
40 #include <dev/hyperv/vmbus/hyperv_common_reg.h>
41 
42 /*
43  * Hyper-V SynIC message format.
44  */
45 
46 #define VMBUS_MSG_DSIZE_MAX		240
47 #define VMBUS_MSG_SIZE			256
48 
49 struct vmbus_message {
50 	uint32_t	msg_type;	/* HYPERV_MSGTYPE_ */
51 	uint8_t		msg_dsize;	/* data size */
52 	uint8_t		msg_flags;	/* VMBUS_MSGFLAG_ */
53 	uint16_t	msg_rsvd;
54 	uint64_t	msg_id;
55 	uint8_t		msg_data[VMBUS_MSG_DSIZE_MAX];
56 } __packed;
57 CTASSERT(sizeof(struct vmbus_message) == VMBUS_MSG_SIZE);
58 
59 #define VMBUS_MSGFLAG_PENDING		0x01
60 
61 /*
62  * Hyper-V SynIC event flags
63  */
64 
65 #ifdef __LP64__
66 #define VMBUS_EVTFLAGS_MAX	32
67 #define VMBUS_EVTFLAG_SHIFT	6
68 #else
69 #define VMBUS_EVTFLAGS_MAX	64
70 #define VMBUS_EVTFLAG_SHIFT	5
71 #endif
72 #define VMBUS_EVTFLAG_LEN	(1 << VMBUS_EVTFLAG_SHIFT)
73 #define VMBUS_EVTFLAG_MASK	(VMBUS_EVTFLAG_LEN - 1)
74 #define VMBUS_EVTFLAGS_SIZE	256
75 
76 struct vmbus_evtflags {
77 	u_long		evt_flags[VMBUS_EVTFLAGS_MAX];
78 } __packed;
79 CTASSERT(sizeof(struct vmbus_evtflags) == VMBUS_EVTFLAGS_SIZE);
80 
81 /*
82  * Hyper-V Monitor Notification Facility
83  */
84 
85 struct vmbus_mon_trig {
86 	uint32_t	mt_pending;
87 	uint32_t	mt_armed;
88 } __packed;
89 
90 #define VMBUS_MONTRIGS_MAX	4
91 #define VMBUS_MONTRIG_LEN	32
92 
93 struct vmbus_mnf {
94 	uint32_t	mnf_state;
95 	uint32_t	mnf_rsvd1;
96 
97 	struct vmbus_mon_trig mnf_trigs[VMBUS_MONTRIGS_MAX];
98 	uint8_t		mnf_rsvd2[536];
99 
100 	uint16_t	mnf_lat[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN];
101 	uint8_t		mnf_rsvd3[256];
102 
103 	struct hyperv_mon_param
104 			mnf_param[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN];
105 	uint8_t		mnf_rsvd4[1984];
106 } __packed;
107 CTASSERT(sizeof(struct vmbus_mnf) == PAGE_SIZE);
108 
109 /*
110  * Buffer ring
111  */
112 struct vmbus_bufring {
113 	/*
114 	 * If br_windex == br_rindex, this bufring is empty; this
115 	 * means we can _not_ write data to the bufring, if the
116 	 * write is going to make br_windex same as br_rindex.
117 	 */
118 	volatile uint32_t	br_windex;
119 	volatile uint32_t	br_rindex;
120 
121 	/*
122 	 * Interrupt mask {0,1}
123 	 *
124 	 * For TX bufring, host set this to 1, when it is processing
125 	 * the TX bufring, so that we can safely skip the TX event
126 	 * notification to host.
127 	 *
128 	 * For RX bufring, once this is set to 1 by us, host will not
129 	 * further dispatch interrupts to us, even if there are data
130 	 * pending on the RX bufring.  This effectively disables the
131 	 * interrupt of the channel to which this RX bufring is attached.
132 	 */
133 	volatile uint32_t	br_imask;
134 
135 	/*
136 	 * WS2012/Win8 and later versions of Hyper-V implement interrupt
137 	 * driven flow management. The feature bit feat_pending_snd_sz
138 	 * is set by the host on the host->guest buffer ring, and by the
139 	 * guest on the guest->host buffer ring.
140 	 *
141 	 * The meaning of the feature bit is a bit complex in that it has
142 	 * semantics that apply to both buffer rings.  If the guest sets
143 	 * the feature bit in the guest->host buffer ring, the guest is
144 	 * telling the host that:
145 	 * 1) It will set the br_pending_snd_sz field in the guest->host buffer
146 	 *    ring when it is waiting for space to become available, and
147 	 * 2) It will read the pending_send_sz field in the host->guest
148 	 *    ring buffer and interrupt the host when it frees enough space
149 	 *
150 	 * Similarly, if the host sets the feature bit in the host->guest
151 	 * ring buffer, the host is telling the guest that:
152 	 * 1) It will set the pending_send_sz field in the host->guest ring
153 	 *    buffer when it is waiting for space to become available, and
154 	 * 2) It will read the pending_send_sz field in the guest->host
155 	 *    ring buffer and interrupt the guest when it frees enough space
156 	 *
157 	 * If either the guest or host does not set the feature bit that it
158 	 * owns, that guest or host must do polling if it encounters a full
159 	 * ring buffer, and not signal the other end with an interrupt.
160 	 */
161 	volatile uint32_t	br_pending_snd_sz;
162 	uint32_t		br_rsvd1[12];
163 	union	{
164 		struct {
165 			uint32_t feat_pending_snd_sz:1;
166 		};
167 		uint32_t value;
168 	} br_feature_bits;
169 
170 	/* Padding to PAGE_SIZE */
171 	uint8_t			br_rsvd2[4020];
172 
173 	/*
174 	 * Total guest to host interrupt count
175 	 * - For rx ring, this counts the guest signaling host when this rx
176 	 * ring changing from full to not full.
177 	 *
178 	 * - For tx ring, this counts the guest signaling host when this tx
179 	 * ring changing from empty to non empty.
180 	 */
181 	uint64_t		br_g2h_intr_cnt;
182 
183 	uint8_t			br_data[];
184 } __packed;
185 CTASSERT(sizeof(struct vmbus_bufring) == PAGE_SIZE);
186 
187 /*
188  * Channel
189  */
190 
191 #define VMBUS_CHAN_MAX_COMPAT	256
192 #define VMBUS_CHAN_MAX		(VMBUS_EVTFLAG_LEN * VMBUS_EVTFLAGS_MAX)
193 
194 /*
195  * Channel packets
196  */
197 
198 #define VMBUS_CHANPKT_SIZE_ALIGN	(1 << VMBUS_CHANPKT_SIZE_SHIFT)
199 
200 #define VMBUS_CHANPKT_SETLEN(pktlen, len)		\
201 do {							\
202 	(pktlen) = (len) >> VMBUS_CHANPKT_SIZE_SHIFT;	\
203 } while (0)
204 
205 #define VMBUS_CHANPKT_TOTLEN(tlen)	\
206 	roundup2((tlen), VMBUS_CHANPKT_SIZE_ALIGN)
207 
208 #define VMBUS_CHANPKT_HLEN_MIN		\
209 	(sizeof(struct vmbus_chanpkt_hdr) >> VMBUS_CHANPKT_SIZE_SHIFT)
210 
211 struct vmbus_chanpkt {
212 	struct vmbus_chanpkt_hdr cp_hdr;
213 } __packed;
214 
215 struct vmbus_chanpkt_sglist {
216 	struct vmbus_chanpkt_hdr cp_hdr;
217 	uint32_t	cp_rsvd;
218 	uint32_t	cp_gpa_cnt;
219 	struct vmbus_gpa cp_gpa[];
220 } __packed;
221 
222 struct vmbus_chanpkt_prplist {
223 	struct vmbus_chanpkt_hdr cp_hdr;
224 	uint32_t	cp_rsvd;
225 	uint32_t	cp_range_cnt;
226 	struct vmbus_gpa_range cp_range[];
227 } __packed;
228 
229 /*
230  * Channel messages
231  * - Embedded in vmbus_message.msg_data, e.g. response and notification.
232  * - Embedded in hypercall_postmsg_in.hc_data, e.g. request.
233  */
234 
235 #define VMBUS_CHANMSG_TYPE_CHOFFER		1	/* NOTE */
236 #define VMBUS_CHANMSG_TYPE_CHRESCIND		2	/* NOTE */
237 #define VMBUS_CHANMSG_TYPE_CHREQUEST		3	/* REQ */
238 #define VMBUS_CHANMSG_TYPE_CHOFFER_DONE		4	/* NOTE */
239 #define VMBUS_CHANMSG_TYPE_CHOPEN		5	/* REQ */
240 #define VMBUS_CHANMSG_TYPE_CHOPEN_RESP		6	/* RESP */
241 #define VMBUS_CHANMSG_TYPE_CHCLOSE		7	/* REQ */
242 #define VMBUS_CHANMSG_TYPE_GPADL_CONN		8	/* REQ */
243 #define VMBUS_CHANMSG_TYPE_GPADL_SUBCONN	9	/* REQ */
244 #define VMBUS_CHANMSG_TYPE_GPADL_CONNRESP	10	/* RESP */
245 #define VMBUS_CHANMSG_TYPE_GPADL_DISCONN	11	/* REQ */
246 #define VMBUS_CHANMSG_TYPE_GPADL_DISCONNRESP	12	/* RESP */
247 #define VMBUS_CHANMSG_TYPE_CHFREE		13	/* REQ */
248 #define VMBUS_CHANMSG_TYPE_CONNECT		14	/* REQ */
249 #define VMBUS_CHANMSG_TYPE_CONNECT_RESP		15	/* RESP */
250 #define VMBUS_CHANMSG_TYPE_DISCONNECT		16	/* REQ */
251 #define VMBUS_CHANMSG_TYPE_17			17
252 #define VMBUS_CHANMSG_TYPE_18			18
253 #define VMBUS_CHANMSG_TYPE_19			19
254 #define VMBUS_CHANMSG_TYPE_20			20
255 #define VMBUS_CHANMSG_TYPE_TL_CONN		21	/* REQ */
256 #define VMBUS_CHANMSG_TYPE_22			22
257 #define VMBUS_CHANMSG_TYPE_TL_RESULT		23	/* RESP */
258 #define VMBUS_CHANMSG_TYPE_MAX			24
259 
260 struct vmbus_chanmsg_hdr {
261 	uint32_t	chm_type;	/* VMBUS_CHANMSG_TYPE_ */
262 	uint32_t	chm_rsvd;
263 } __packed;
264 
265 /* VMBUS_CHANMSG_TYPE_CONNECT */
266 struct vmbus_chanmsg_connect {
267 	struct vmbus_chanmsg_hdr chm_hdr;
268 	uint32_t	chm_ver;
269 	uint32_t	chm_rsvd;
270 	uint64_t	chm_evtflags;
271 	uint64_t	chm_mnf1;
272 	uint64_t	chm_mnf2;
273 } __packed;
274 
275 /* VMBUS_CHANMSG_TYPE_CONNECT_RESP */
276 struct vmbus_chanmsg_connect_resp {
277 	struct vmbus_chanmsg_hdr chm_hdr;
278 	uint8_t		chm_done;
279 } __packed;
280 
281 /* VMBUS_CHANMSG_TYPE_CHREQUEST */
282 struct vmbus_chanmsg_chrequest {
283 	struct vmbus_chanmsg_hdr chm_hdr;
284 } __packed;
285 
286 /* VMBUS_CHANMSG_TYPE_DISCONNECT */
287 struct vmbus_chanmsg_disconnect {
288 	struct vmbus_chanmsg_hdr chm_hdr;
289 } __packed;
290 
291 /* VMBUS_CHANMSG_TYPE_TL_CONN */
292 /* Hyper-V socket guest connect request */
293 struct vmbus_chanmsg_tl_connect {
294 	struct vmbus_chanmsg_hdr chm_hdr;
295 	struct hyperv_guid guest_endpoint_id;
296 	struct hyperv_guid host_service_id;
297 } __packed;
298 
299 
300 /* VMBUS_CHANMSG_TYPE_CHOPEN */
301 struct vmbus_chanmsg_chopen {
302 	struct vmbus_chanmsg_hdr chm_hdr;
303 	uint32_t	chm_chanid;
304 	uint32_t	chm_openid;
305 	uint32_t	chm_gpadl;
306 	uint32_t	chm_vcpuid;
307 	uint32_t	chm_txbr_pgcnt;
308 #define VMBUS_CHANMSG_CHOPEN_UDATA_SIZE	120
309 	uint8_t		chm_udata[VMBUS_CHANMSG_CHOPEN_UDATA_SIZE];
310 } __packed;
311 
312 /* VMBUS_CHANMSG_TYPE_CHOPEN_RESP */
313 struct vmbus_chanmsg_chopen_resp {
314 	struct vmbus_chanmsg_hdr chm_hdr;
315 	uint32_t	chm_chanid;
316 	uint32_t	chm_openid;
317 	uint32_t	chm_status;
318 } __packed;
319 
320 /* VMBUS_CHANMSG_TYPE_GPADL_CONN */
321 struct vmbus_chanmsg_gpadl_conn {
322 	struct vmbus_chanmsg_hdr chm_hdr;
323 	uint32_t	chm_chanid;
324 	uint32_t	chm_gpadl;
325 	uint16_t	chm_range_len;
326 	uint16_t	chm_range_cnt;
327 	struct vmbus_gpa_range chm_range;
328 } __packed;
329 
330 #define VMBUS_CHANMSG_GPADL_CONN_PGMAX		26
331 CTASSERT(__offsetof(struct vmbus_chanmsg_gpadl_conn,
332     chm_range.gpa_page[VMBUS_CHANMSG_GPADL_CONN_PGMAX]) <=
333     HYPERCALL_POSTMSGIN_DSIZE_MAX);
334 
335 /* VMBUS_CHANMSG_TYPE_GPADL_SUBCONN */
336 struct vmbus_chanmsg_gpadl_subconn {
337 	struct vmbus_chanmsg_hdr chm_hdr;
338 	uint32_t	chm_msgno;
339 	uint32_t	chm_gpadl;
340 	uint64_t	chm_gpa_page[];
341 } __packed;
342 
343 #define VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX	28
344 CTASSERT(__offsetof(struct vmbus_chanmsg_gpadl_subconn,
345     chm_gpa_page[VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX]) <=
346     HYPERCALL_POSTMSGIN_DSIZE_MAX);
347 
348 /* VMBUS_CHANMSG_TYPE_GPADL_CONNRESP */
349 struct vmbus_chanmsg_gpadl_connresp {
350 	struct vmbus_chanmsg_hdr chm_hdr;
351 	uint32_t	chm_chanid;
352 	uint32_t	chm_gpadl;
353 	uint32_t	chm_status;
354 } __packed;
355 
356 /* VMBUS_CHANMSG_TYPE_CHCLOSE */
357 struct vmbus_chanmsg_chclose {
358 	struct vmbus_chanmsg_hdr chm_hdr;
359 	uint32_t	chm_chanid;
360 } __packed;
361 
362 /* VMBUS_CHANMSG_TYPE_GPADL_DISCONN */
363 struct vmbus_chanmsg_gpadl_disconn {
364 	struct vmbus_chanmsg_hdr chm_hdr;
365 	uint32_t	chm_chanid;
366 	uint32_t	chm_gpadl;
367 } __packed;
368 
369 /* VMBUS_CHANMSG_TYPE_CHFREE */
370 struct vmbus_chanmsg_chfree {
371 	struct vmbus_chanmsg_hdr chm_hdr;
372 	uint32_t	chm_chanid;
373 } __packed;
374 
375 /* VMBUS_CHANMSG_TYPE_CHRESCIND */
376 struct vmbus_chanmsg_chrescind {
377 	struct vmbus_chanmsg_hdr chm_hdr;
378 	uint32_t	chm_chanid;
379 } __packed;
380 
381 /* Size of the user defined data buffer for non-pipe offers */
382 #define VMBUS_CHANMSG_CHOFFER_UDATA_SIZE		120
383 
384 /* Size of the user defined data buffer for pipe offers. */
385 #define VMBUS_CHANMSG_CHOFFER_UDATA_PIPE_SIZE		116
386 
387 /* VMBUS_CHANMSG_TYPE_CHOFFER */
388 struct vmbus_chanmsg_choffer {
389 	struct vmbus_chanmsg_hdr chm_hdr;
390 	struct hyperv_guid chm_chtype;
391 	struct hyperv_guid chm_chinst;
392 	uint64_t	chm_chlat;	/* unit: 100ns */
393 	uint32_t	chm_chrev;
394 	uint32_t	chm_svrctx_sz;
395 	uint16_t	chm_chflags;
396 	uint16_t	chm_mmio_sz;	/* unit: MB */
397 
398 	union {
399 		/* Non-pipes */
400 		struct {
401 			uint8_t	user_def[VMBUS_CHANMSG_CHOFFER_UDATA_SIZE];
402 		} std;
403 		/*
404 		 * Pipes:
405 		 * For integrated pipe protocol, which is implemented on
406 		 * top of standard user-defined data. Pipe clients have
407 		 * VMBUS_CHANMSG_CHOFFER_UDATA_PIPE_SIZE bytes left for
408 		 * their own user.
409 		 */
410 		struct {
411 			uint32_t pipe_mode;
412 			uint8_t
413 			    user_def[VMBUS_CHANMSG_CHOFFER_UDATA_PIPE_SIZE];
414 		} pipe;
415 	} chm_udata;
416 
417 	uint16_t	chm_subidx;
418 	uint16_t	chm_rsvd;
419 	uint32_t	chm_chanid;
420 	uint8_t		chm_montrig;
421 	uint8_t		chm_flags1;	/* VMBUS_CHOFFER_FLAG1_ */
422 	uint16_t	chm_flags2;
423 	uint32_t	chm_connid;
424 } __packed;
425 CTASSERT(sizeof(struct vmbus_chanmsg_choffer) <= VMBUS_MSG_DSIZE_MAX);
426 
427 /* Server Flag */
428 #define VMBUS_CHAN_TLNPI_PROVIDER_OFFER			0x2000
429 
430 #define VMBUS_CHOFFER_FLAG1_HASMNF	0x01
431 
432 #endif	/* !_VMBUS_REG_H_ */
433