xref: /netbsd/sys/dev/hyperv/hypervreg.h (revision c2ac0d61)
1 /*	$NetBSD: hypervreg.h,v 1.2 2022/05/20 13:55:17 nonaka Exp $	*/
2 /*	$OpenBSD: hypervreg.h,v 1.10 2017/01/05 13:17:22 mikeb Exp $	*/
3 
4 /*-
5  * Copyright (c) 2009-2012,2016 Microsoft Corp.
6  * Copyright (c) 2012 NetApp Inc.
7  * Copyright (c) 2012 Citrix Inc.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice unmodified, this list of conditions, and the following
15  *    disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _HYPERVREG_H_
33 #define _HYPERVREG_H_
34 
35 #if defined(_KERNEL)
36 
37 #define VMBUS_CONNID_MESSAGE		1
38 #define VMBUS_CONNID_EVENT		2
39 #define VMBUS_SINT_MESSAGE		2
40 #define VMBUS_SINT_TIMER		4
41 
42 struct hyperv_guid {
43 	uint8_t		hv_guid[16];
44 } __packed;
45 
46 /*
47  * $FreeBSD: head/sys/dev/hyperv/vmbus/hyperv_reg.h 303283 2016-07-25 03:12:40Z sephe $
48  */
49 
50 /*
51  * Hyper-V Monitor Notification Facility
52  */
53 struct hyperv_mon_param {
54 	uint32_t	mp_connid;
55 	uint16_t	mp_evtflag_ofs;
56 	uint16_t	mp_rsvd;
57 } __packed;
58 
59 /*
60  * Hyper-V message types
61  */
62 #define HYPERV_MSGTYPE_NONE		0
63 #define HYPERV_MSGTYPE_CHANNEL		1
64 #define HYPERV_MSGTYPE_TIMER_EXPIRED	0x80000010
65 
66 /*
67  * Hypercall status codes
68  */
69 #define HYPERCALL_STATUS_SUCCESS	0x0000
70 
71 /*
72  * Hypercall input values
73  */
74 #define HYPERCALL_POST_MESSAGE		0x005c
75 #define HYPERCALL_SIGNAL_EVENT		0x005d
76 
77 /*
78  * Hypercall input parameters
79  */
80 #define HYPERCALL_PARAM_ALIGN		8
81 #if 0
82 /*
83  * XXX
84  * <<Hypervisor Top Level Functional Specification 4.0b>> requires
85  * input parameters size to be multiple of 8, however, many post
86  * message input parameters do _not_ meet this requirement.
87  */
88 #define HYPERCALL_PARAM_SIZE_ALIGN	8
89 #endif
90 
91 /*
92  * HYPERCALL_POST_MESSAGE
93  */
94 #define HYPERCALL_POSTMSGIN_DSIZE_MAX	240
95 #define HYPERCALL_POSTMSGIN_SIZE	256
96 
97 struct hyperv_hypercall_postmsg_in {
98 	uint32_t	hc_connid;
99 	uint32_t	hc_rsvd;
100 	uint32_t	hc_msgtype;	/* VMBUS_MSGTYPE_ */
101 	uint32_t	hc_dsize;
102 	uint8_t		hc_data[HYPERCALL_POSTMSGIN_DSIZE_MAX];
103 } __packed;
104 __CTASSERT(sizeof(struct hyperv_hypercall_postmsg_in) == HYPERCALL_POSTMSGIN_SIZE);
105 
106 /*
107  * $FreeBSD: head/sys/dev/hyperv/include/vmbus.h 306389 2016-09-28 04:25:25Z sephe $
108  */
109 
110 /*
111  * VMBUS version is 32 bit, upper 16 bit for major_number and lower
112  * 16 bit for minor_number.
113  *
114  * 0.13  --  Windows Server 2008
115  * 1.1   --  Windows 7
116  * 2.4   --  Windows 8
117  * 3.0   --  Windows 8.1
118  * 4.0   --  Windows 10
119  */
120 #define VMBUS_VERSION_WS2008		((0 << 16) | (13))
121 #define VMBUS_VERSION_WIN7		((1 << 16) | (1))
122 #define VMBUS_VERSION_WIN8		((2 << 16) | (4))
123 #define VMBUS_VERSION_WIN8_1		((3 << 16) | (0))
124 #define VMBUS_VERSION_WIN10		((4 << 16) | (0))
125 
126 #define VMBUS_VERSION_MAJOR(ver)	(((uint32_t)(ver)) >> 16)
127 #define VMBUS_VERSION_MINOR(ver)	(((uint32_t)(ver)) & 0xffff)
128 
129 /*
130  * GPA stuffs.
131  */
132 struct vmbus_gpa_range {
133 	uint32_t	gpa_len;
134 	uint32_t	gpa_ofs;
135 	uint64_t	gpa_page[0];
136 } __packed;
137 
138 /* This is actually vmbus_gpa_range.gpa_page[1] */
139 struct vmbus_gpa {
140 	uint32_t	gpa_len;
141 	uint32_t	gpa_ofs;
142 	uint64_t	gpa_page;
143 } __packed;
144 
145 #define VMBUS_CHANPKT_SIZE_SHIFT	3
146 
147 #define VMBUS_CHANPKT_GETLEN(pktlen)	\
148 	(((int)(pktlen)) << VMBUS_CHANPKT_SIZE_SHIFT)
149 
150 struct vmbus_chanpkt_hdr {
151 	uint16_t	cph_type;	/* VMBUS_CHANPKT_TYPE_ */
152 	uint16_t	cph_hlen;	/* header len, in 8 bytes */
153 	uint16_t	cph_tlen;	/* total len, in 8 bytes */
154 	uint16_t	cph_flags;	/* VMBUS_CHANPKT_FLAG_ */
155 	uint64_t	cph_tid;
156 } __packed;
157 
158 #define VMBUS_CHANPKT_TYPE_INBAND	0x0006
159 #define VMBUS_CHANPKT_TYPE_RXBUF	0x0007
160 #define VMBUS_CHANPKT_TYPE_GPA		0x0009
161 #define VMBUS_CHANPKT_TYPE_COMP		0x000b
162 
163 #define VMBUS_CHANPKT_FLAG_RC		0x0001	/* report completion */
164 
165 #define VMBUS_CHANPKT_CONST_DATA(pkt)			\
166 	((const void *)((const uint8_t *)(pkt) +	\
167 	    VMBUS_CHANPKT_GETLEN((pkt)->cph_hlen)))
168 
169 /*
170  * $FreeBSD: head/sys/dev/hyperv/vmbus/vmbus_reg.h 305405 2016-09-05 03:21:31Z sephe $
171  */
172 
173 /*
174  * Hyper-V SynIC message format.
175  */
176 
177 #define VMBUS_MSG_DSIZE_MAX		240
178 #define VMBUS_MSG_SIZE			256
179 
180 struct vmbus_message {
181 	uint32_t	msg_type;	/* VMBUS_MSGTYPE_ */
182 	uint8_t		msg_dsize;	/* data size */
183 	uint8_t		msg_flags;	/* VMBUS_MSGFLAG_ */
184 	uint16_t	msg_rsvd;
185 	uint64_t	msg_id;
186 	uint8_t		msg_data[VMBUS_MSG_DSIZE_MAX];
187 } __packed;
188 
189 #define VMBUS_MSGFLAG_PENDING		0x01
190 
191 /*
192  * Hyper-V SynIC event flags
193  */
194 
195 #define VMBUS_EVTFLAGS_SIZE	256
196 #define VMBUS_EVTFLAGS_MAX	((VMBUS_EVTFLAGS_SIZE / LONG_BIT) * 8)
197 #define VMBUS_EVTFLAG_LEN	LONG_BIT
198 #define VMBUS_EVTFLAG_MASK	(LONG_BIT - 1)
199 
200 struct vmbus_evtflags {
201 	ulong		evt_flags[VMBUS_EVTFLAGS_MAX];
202 } __packed;
203 
204 /*
205  * Hyper-V Monitor Notification Facility
206  */
207 
208 struct vmbus_mon_trig {
209 	uint32_t	mt_pending;
210 	uint32_t	mt_armed;
211 } __packed;
212 
213 #define VMBUS_MONTRIGS_MAX	4
214 #define VMBUS_MONTRIG_LEN	32
215 
216 struct vmbus_mnf {
217 	uint32_t	mnf_state;
218 	uint32_t	mnf_rsvd1;
219 
220 	struct vmbus_mon_trig
221 			mnf_trigs[VMBUS_MONTRIGS_MAX];
222 	uint8_t		mnf_rsvd2[536];
223 
224 	uint16_t	mnf_lat[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN];
225 	uint8_t		mnf_rsvd3[256];
226 
227 	struct hyperv_mon_param
228 			mnf_param[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN];
229 	uint8_t		mnf_rsvd4[1984];
230 } __packed;
231 
232 /*
233  * Buffer ring
234  */
235 struct vmbus_bufring {
236 	/*
237 	 * If br_windex == br_rindex, this bufring is empty; this
238 	 * means we can _not_ write data to the bufring, if the
239 	 * write is going to make br_windex same as br_rindex.
240 	 */
241 	volatile uint32_t	br_windex;
242 	volatile uint32_t	br_rindex;
243 
244 	/*
245 	 * Interrupt mask {0,1}
246 	 *
247 	 * For TX bufring, host set this to 1, when it is processing
248 	 * the TX bufring, so that we can safely skip the TX event
249 	 * notification to host.
250 	 *
251 	 * For RX bufring, once this is set to 1 by us, host will not
252 	 * further dispatch interrupts to us, even if there are data
253 	 * pending on the RX bufring.  This effectively disables the
254 	 * interrupt of the channel to which this RX bufring is attached.
255 	 */
256 	volatile uint32_t	br_imask;
257 
258 	uint8_t			br_rsvd[4084];
259 	uint8_t			br_data[0];
260 } __packed;
261 __CTASSERT(sizeof(struct vmbus_bufring) == PAGE_SIZE);
262 
263 /*
264  * Channel
265  */
266 
267 #define VMBUS_CHAN_MAX_COMPAT	256
268 #define VMBUS_CHAN_MAX		(VMBUS_EVTFLAG_LEN * VMBUS_EVTFLAGS_MAX)
269 
270 /*
271  * Channel packets
272  */
273 
274 #define VMBUS_CHANPKT_SIZE_ALIGN	(1 << VMBUS_CHANPKT_SIZE_SHIFT)
275 
276 #define VMBUS_CHANPKT_SETLEN(pktlen, len)		\
277 do {							\
278 	(pktlen) = (len) >> VMBUS_CHANPKT_SIZE_SHIFT;	\
279 } while (0)
280 
281 struct vmbus_chanpkt {
282 	struct vmbus_chanpkt_hdr cp_hdr;
283 } __packed;
284 
285 struct vmbus_chanpkt_sglist {
286 	struct vmbus_chanpkt_hdr cp_hdr;
287 	uint32_t	cp_rsvd;
288 	uint32_t	cp_gpa_cnt;
289 	struct vmbus_gpa cp_gpa[0];
290 } __packed;
291 
292 struct vmbus_chanpkt_prplist {
293 	struct vmbus_chanpkt_hdr cp_hdr;
294 	uint32_t	cp_rsvd;
295 	uint32_t	cp_range_cnt;
296 	struct vmbus_gpa_range cp_range[0];
297 } __packed;
298 
299 /*
300  * Channel messages
301  * - Embedded in vmbus_message.msg_data, e.g. response and notification.
302  * - Embedded in hyperv_hypercall_postmsg_in.hc_data, e.g. request.
303  */
304 
305 #define VMBUS_CHANMSG_CHOFFER			1	/* NOTE */
306 #define VMBUS_CHANMSG_CHRESCIND			2	/* NOTE */
307 #define VMBUS_CHANMSG_CHREQUEST			3	/* REQ */
308 #define VMBUS_CHANMSG_CHOFFER_DONE		4	/* NOTE */
309 #define VMBUS_CHANMSG_CHOPEN			5	/* REQ */
310 #define VMBUS_CHANMSG_CHOPEN_RESP		6	/* RESP */
311 #define VMBUS_CHANMSG_CHCLOSE			7	/* REQ */
312 #define VMBUS_CHANMSG_GPADL_CONN		8	/* REQ */
313 #define VMBUS_CHANMSG_GPADL_SUBCONN		9	/* REQ */
314 #define VMBUS_CHANMSG_GPADL_CONNRESP		10	/* RESP */
315 #define VMBUS_CHANMSG_GPADL_DISCONN		11	/* REQ */
316 #define VMBUS_CHANMSG_GPADL_DISCONNRESP		12	/* RESP */
317 #define VMBUS_CHANMSG_CHFREE			13	/* REQ */
318 #define VMBUS_CHANMSG_CONNECT			14	/* REQ */
319 #define VMBUS_CHANMSG_CONNECT_RESP		15	/* RESP */
320 #define VMBUS_CHANMSG_DISCONNECT		16	/* REQ */
321 #define VMBUS_CHANMSG_COUNT			17
322 #define VMBUS_CHANMSG_MAX			22
323 
324 struct vmbus_chanmsg_hdr {
325 	uint32_t	chm_type;	/* VMBUS_CHANMSG_* */
326 	uint32_t	chm_rsvd;
327 } __packed;
328 
329 /* VMBUS_CHANMSG_CONNECT */
330 struct vmbus_chanmsg_connect {
331 	struct vmbus_chanmsg_hdr chm_hdr;
332 	uint32_t	chm_ver;
333 	uint32_t	chm_rsvd;
334 	uint64_t	chm_evtflags;
335 	uint64_t	chm_mnf1;
336 	uint64_t	chm_mnf2;
337 } __packed;
338 
339 /* VMBUS_CHANMSG_CONNECT_RESP */
340 struct vmbus_chanmsg_connect_resp {
341 	struct vmbus_chanmsg_hdr chm_hdr;
342 	uint8_t		chm_done;
343 } __packed;
344 
345 /* VMBUS_CHANMSG_CHREQUEST */
346 struct vmbus_chanmsg_chrequest {
347 	struct vmbus_chanmsg_hdr chm_hdr;
348 } __packed;
349 
350 /* VMBUS_CHANMSG_DISCONNECT */
351 struct vmbus_chanmsg_disconnect {
352 	struct vmbus_chanmsg_hdr chm_hdr;
353 } __packed;
354 
355 /* VMBUS_CHANMSG_CHOPEN */
356 struct vmbus_chanmsg_chopen {
357 	struct vmbus_chanmsg_hdr chm_hdr;
358 	uint32_t	chm_chanid;
359 	uint32_t	chm_openid;
360 	uint32_t	chm_gpadl;
361 	uint32_t	chm_vcpuid;
362 	uint32_t	chm_txbr_pgcnt;
363 #define VMBUS_CHANMSG_CHOPEN_UDATA_SIZE	120
364 	uint8_t		chm_udata[VMBUS_CHANMSG_CHOPEN_UDATA_SIZE];
365 } __packed;
366 
367 /* VMBUS_CHANMSG_CHOPEN_RESP */
368 struct vmbus_chanmsg_chopen_resp {
369 	struct vmbus_chanmsg_hdr chm_hdr;
370 	uint32_t	chm_chanid;
371 	uint32_t	chm_openid;
372 	uint32_t	chm_status;
373 } __packed;
374 
375 /* VMBUS_CHANMSG_GPADL_CONN */
376 struct vmbus_chanmsg_gpadl_conn {
377 	struct vmbus_chanmsg_hdr chm_hdr;
378 	uint32_t	chm_chanid;
379 	uint32_t	chm_gpadl;
380 	uint16_t	chm_range_len;
381 	uint16_t	chm_range_cnt;
382 	struct vmbus_gpa_range chm_range;
383 } __packed;
384 
385 #define VMBUS_CHANMSG_GPADL_CONN_PGMAX		26
386 
387 /* VMBUS_CHANMSG_GPADL_SUBCONN */
388 struct vmbus_chanmsg_gpadl_subconn {
389 	struct vmbus_chanmsg_hdr chm_hdr;
390 	uint32_t	chm_msgno;
391 	uint32_t	chm_gpadl;
392 	uint64_t	chm_gpa_page[0];
393 } __packed;
394 
395 #define VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX	28
396 
397 /* VMBUS_CHANMSG_GPADL_CONNRESP */
398 struct vmbus_chanmsg_gpadl_connresp {
399 	struct vmbus_chanmsg_hdr chm_hdr;
400 	uint32_t	chm_chanid;
401 	uint32_t	chm_gpadl;
402 	uint32_t	chm_status;
403 } __packed;
404 
405 /* VMBUS_CHANMSG_CHCLOSE */
406 struct vmbus_chanmsg_chclose {
407 	struct vmbus_chanmsg_hdr chm_hdr;
408 	uint32_t	chm_chanid;
409 } __packed;
410 
411 /* VMBUS_CHANMSG_GPADL_DISCONN */
412 struct vmbus_chanmsg_gpadl_disconn {
413 	struct vmbus_chanmsg_hdr chm_hdr;
414 	uint32_t	chm_chanid;
415 	uint32_t	chm_gpadl;
416 } __packed;
417 
418 /* VMBUS_CHANMSG_CHFREE */
419 struct vmbus_chanmsg_chfree {
420 	struct vmbus_chanmsg_hdr chm_hdr;
421 	uint32_t	chm_chanid;
422 } __packed;
423 
424 /* VMBUS_CHANMSG_CHRESCIND */
425 struct vmbus_chanmsg_chrescind {
426 	struct vmbus_chanmsg_hdr chm_hdr;
427 	uint32_t	chm_chanid;
428 } __packed;
429 
430 /* VMBUS_CHANMSG_CHOFFER */
431 struct vmbus_chanmsg_choffer {
432 	struct vmbus_chanmsg_hdr chm_hdr;
433 	struct hyperv_guid chm_chtype;
434 	struct hyperv_guid chm_chinst;
435 	uint64_t	chm_chlat;	/* unit: 100ns */
436 	uint32_t	chm_chrev;
437 	uint32_t	chm_svrctx_sz;
438 	uint16_t	chm_chflags;
439 	uint16_t	chm_mmio_sz;	/* unit: MB */
440 	uint8_t		chm_udata[120];
441 	uint16_t	chm_subidx;
442 	uint16_t	chm_rsvd;
443 	uint32_t	chm_chanid;
444 	uint8_t		chm_montrig;
445 	uint8_t		chm_flags1;	/* VMBUS_CHOFFER_FLAG1_ */
446 	uint16_t	chm_flags2;
447 	uint32_t	chm_connid;
448 } __packed;
449 
450 #define VMBUS_CHOFFER_FLAG1_HASMNF	0x01
451 
452 #endif	/* _KERNEL */
453 
454 #endif	/* _HYPERVREG_H_ */
455