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
42struct 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 */
53struct 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
97struct 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 */
132struct 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] */
139struct 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
150struct 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
180struct 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
200struct vmbus_evtflags {
201	ulong		evt_flags[VMBUS_EVTFLAGS_MAX];
202} __packed;
203
204/*
205 * Hyper-V Monitor Notification Facility
206 */
207
208struct 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
216struct 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 */
235struct 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)		\
277do {							\
278	(pktlen) = (len) >> VMBUS_CHANPKT_SIZE_SHIFT;	\
279} while (0)
280
281struct vmbus_chanpkt {
282	struct vmbus_chanpkt_hdr cp_hdr;
283} __packed;
284
285struct 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
292struct 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
324struct vmbus_chanmsg_hdr {
325	uint32_t	chm_type;	/* VMBUS_CHANMSG_* */
326	uint32_t	chm_rsvd;
327} __packed;
328
329/* VMBUS_CHANMSG_CONNECT */
330struct 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 */
340struct vmbus_chanmsg_connect_resp {
341	struct vmbus_chanmsg_hdr chm_hdr;
342	uint8_t		chm_done;
343} __packed;
344
345/* VMBUS_CHANMSG_CHREQUEST */
346struct vmbus_chanmsg_chrequest {
347	struct vmbus_chanmsg_hdr chm_hdr;
348} __packed;
349
350/* VMBUS_CHANMSG_DISCONNECT */
351struct vmbus_chanmsg_disconnect {
352	struct vmbus_chanmsg_hdr chm_hdr;
353} __packed;
354
355/* VMBUS_CHANMSG_CHOPEN */
356struct 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 */
368struct 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 */
376struct 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 */
388struct 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 */
398struct 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 */
406struct vmbus_chanmsg_chclose {
407	struct vmbus_chanmsg_hdr chm_hdr;
408	uint32_t	chm_chanid;
409} __packed;
410
411/* VMBUS_CHANMSG_GPADL_DISCONN */
412struct 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 */
419struct vmbus_chanmsg_chfree {
420	struct vmbus_chanmsg_hdr chm_hdr;
421	uint32_t	chm_chanid;
422} __packed;
423
424/* VMBUS_CHANMSG_CHRESCIND */
425struct vmbus_chanmsg_chrescind {
426	struct vmbus_chanmsg_hdr chm_hdr;
427	uint32_t	chm_chanid;
428} __packed;
429
430/* VMBUS_CHANMSG_CHOFFER */
431struct 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