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: stable/11/sys/dev/hyperv/vmbus/vmbus_reg.h 307498 2016-10-17 08:10:24Z sephe $
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#include <dev/hyperv/vmbus/hyperv_reg.h>
36
37/*
38 * Hyper-V SynIC message format.
39 */
40
41#define VMBUS_MSG_DSIZE_MAX		240
42#define VMBUS_MSG_SIZE			256
43
44struct vmbus_message {
45	uint32_t	msg_type;	/* HYPERV_MSGTYPE_ */
46	uint8_t		msg_dsize;	/* data size */
47	uint8_t		msg_flags;	/* VMBUS_MSGFLAG_ */
48	uint16_t	msg_rsvd;
49	uint64_t	msg_id;
50	uint8_t		msg_data[VMBUS_MSG_DSIZE_MAX];
51} __packed;
52CTASSERT(sizeof(struct vmbus_message) == VMBUS_MSG_SIZE);
53
54#define VMBUS_MSGFLAG_PENDING		0x01
55
56/*
57 * Hyper-V SynIC event flags
58 */
59
60#ifdef __LP64__
61#define VMBUS_EVTFLAGS_MAX	32
62#define VMBUS_EVTFLAG_SHIFT	6
63#else
64#define VMBUS_EVTFLAGS_MAX	64
65#define VMBUS_EVTFLAG_SHIFT	5
66#endif
67#define VMBUS_EVTFLAG_LEN	(1 << VMBUS_EVTFLAG_SHIFT)
68#define VMBUS_EVTFLAG_MASK	(VMBUS_EVTFLAG_LEN - 1)
69#define VMBUS_EVTFLAGS_SIZE	256
70
71struct vmbus_evtflags {
72	u_long		evt_flags[VMBUS_EVTFLAGS_MAX];
73} __packed;
74CTASSERT(sizeof(struct vmbus_evtflags) == VMBUS_EVTFLAGS_SIZE);
75
76/*
77 * Hyper-V Monitor Notification Facility
78 */
79
80struct vmbus_mon_trig {
81	uint32_t	mt_pending;
82	uint32_t	mt_armed;
83} __packed;
84
85#define VMBUS_MONTRIGS_MAX	4
86#define VMBUS_MONTRIG_LEN	32
87
88struct vmbus_mnf {
89	uint32_t	mnf_state;
90	uint32_t	mnf_rsvd1;
91
92	struct vmbus_mon_trig mnf_trigs[VMBUS_MONTRIGS_MAX];
93	uint8_t		mnf_rsvd2[536];
94
95	uint16_t	mnf_lat[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN];
96	uint8_t		mnf_rsvd3[256];
97
98	struct hyperv_mon_param
99			mnf_param[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN];
100	uint8_t		mnf_rsvd4[1984];
101} __packed;
102CTASSERT(sizeof(struct vmbus_mnf) == PAGE_SIZE);
103
104/*
105 * Buffer ring
106 */
107struct vmbus_bufring {
108	/*
109	 * If br_windex == br_rindex, this bufring is empty; this
110	 * means we can _not_ write data to the bufring, if the
111	 * write is going to make br_windex same as br_rindex.
112	 */
113	volatile uint32_t	br_windex;
114	volatile uint32_t	br_rindex;
115
116	/*
117	 * Interrupt mask {0,1}
118	 *
119	 * For TX bufring, host set this to 1, when it is processing
120	 * the TX bufring, so that we can safely skip the TX event
121	 * notification to host.
122	 *
123	 * For RX bufring, once this is set to 1 by us, host will not
124	 * further dispatch interrupts to us, even if there are data
125	 * pending on the RX bufring.  This effectively disables the
126	 * interrupt of the channel to which this RX bufring is attached.
127	 */
128	volatile uint32_t	br_imask;
129
130	uint8_t			br_rsvd[4084];
131	uint8_t			br_data[];
132} __packed;
133CTASSERT(sizeof(struct vmbus_bufring) == PAGE_SIZE);
134
135/*
136 * Channel
137 */
138
139#define VMBUS_CHAN_MAX_COMPAT	256
140#define VMBUS_CHAN_MAX		(VMBUS_EVTFLAG_LEN * VMBUS_EVTFLAGS_MAX)
141
142/*
143 * Channel packets
144 */
145
146#define VMBUS_CHANPKT_SIZE_ALIGN	(1 << VMBUS_CHANPKT_SIZE_SHIFT)
147
148#define VMBUS_CHANPKT_SETLEN(pktlen, len)		\
149do {							\
150	(pktlen) = (len) >> VMBUS_CHANPKT_SIZE_SHIFT;	\
151} while (0)
152
153#define VMBUS_CHANPKT_TOTLEN(tlen)	\
154	roundup2((tlen), VMBUS_CHANPKT_SIZE_ALIGN)
155
156#define VMBUS_CHANPKT_HLEN_MIN		\
157	(sizeof(struct vmbus_chanpkt_hdr) >> VMBUS_CHANPKT_SIZE_SHIFT)
158
159struct vmbus_chanpkt {
160	struct vmbus_chanpkt_hdr cp_hdr;
161} __packed;
162
163struct vmbus_chanpkt_sglist {
164	struct vmbus_chanpkt_hdr cp_hdr;
165	uint32_t	cp_rsvd;
166	uint32_t	cp_gpa_cnt;
167	struct vmbus_gpa cp_gpa[];
168} __packed;
169
170struct vmbus_chanpkt_prplist {
171	struct vmbus_chanpkt_hdr cp_hdr;
172	uint32_t	cp_rsvd;
173	uint32_t	cp_range_cnt;
174	struct vmbus_gpa_range cp_range[];
175} __packed;
176
177/*
178 * Channel messages
179 * - Embedded in vmbus_message.msg_data, e.g. response and notification.
180 * - Embedded in hypercall_postmsg_in.hc_data, e.g. request.
181 */
182
183#define VMBUS_CHANMSG_TYPE_CHOFFER		1	/* NOTE */
184#define VMBUS_CHANMSG_TYPE_CHRESCIND		2	/* NOTE */
185#define VMBUS_CHANMSG_TYPE_CHREQUEST		3	/* REQ */
186#define VMBUS_CHANMSG_TYPE_CHOFFER_DONE		4	/* NOTE */
187#define VMBUS_CHANMSG_TYPE_CHOPEN		5	/* REQ */
188#define VMBUS_CHANMSG_TYPE_CHOPEN_RESP		6	/* RESP */
189#define VMBUS_CHANMSG_TYPE_CHCLOSE		7	/* REQ */
190#define VMBUS_CHANMSG_TYPE_GPADL_CONN		8	/* REQ */
191#define VMBUS_CHANMSG_TYPE_GPADL_SUBCONN	9	/* REQ */
192#define VMBUS_CHANMSG_TYPE_GPADL_CONNRESP	10	/* RESP */
193#define VMBUS_CHANMSG_TYPE_GPADL_DISCONN	11	/* REQ */
194#define VMBUS_CHANMSG_TYPE_GPADL_DISCONNRESP	12	/* RESP */
195#define VMBUS_CHANMSG_TYPE_CHFREE		13	/* REQ */
196#define VMBUS_CHANMSG_TYPE_CONNECT		14	/* REQ */
197#define VMBUS_CHANMSG_TYPE_CONNECT_RESP		15	/* RESP */
198#define VMBUS_CHANMSG_TYPE_DISCONNECT		16	/* REQ */
199#define VMBUS_CHANMSG_TYPE_MAX			22
200
201struct vmbus_chanmsg_hdr {
202	uint32_t	chm_type;	/* VMBUS_CHANMSG_TYPE_ */
203	uint32_t	chm_rsvd;
204} __packed;
205
206/* VMBUS_CHANMSG_TYPE_CONNECT */
207struct vmbus_chanmsg_connect {
208	struct vmbus_chanmsg_hdr chm_hdr;
209	uint32_t	chm_ver;
210	uint32_t	chm_rsvd;
211	uint64_t	chm_evtflags;
212	uint64_t	chm_mnf1;
213	uint64_t	chm_mnf2;
214} __packed;
215
216/* VMBUS_CHANMSG_TYPE_CONNECT_RESP */
217struct vmbus_chanmsg_connect_resp {
218	struct vmbus_chanmsg_hdr chm_hdr;
219	uint8_t		chm_done;
220} __packed;
221
222/* VMBUS_CHANMSG_TYPE_CHREQUEST */
223struct vmbus_chanmsg_chrequest {
224	struct vmbus_chanmsg_hdr chm_hdr;
225} __packed;
226
227/* VMBUS_CHANMSG_TYPE_DISCONNECT */
228struct vmbus_chanmsg_disconnect {
229	struct vmbus_chanmsg_hdr chm_hdr;
230} __packed;
231
232/* VMBUS_CHANMSG_TYPE_CHOPEN */
233struct vmbus_chanmsg_chopen {
234	struct vmbus_chanmsg_hdr chm_hdr;
235	uint32_t	chm_chanid;
236	uint32_t	chm_openid;
237	uint32_t	chm_gpadl;
238	uint32_t	chm_vcpuid;
239	uint32_t	chm_txbr_pgcnt;
240#define VMBUS_CHANMSG_CHOPEN_UDATA_SIZE	120
241	uint8_t		chm_udata[VMBUS_CHANMSG_CHOPEN_UDATA_SIZE];
242} __packed;
243
244/* VMBUS_CHANMSG_TYPE_CHOPEN_RESP */
245struct vmbus_chanmsg_chopen_resp {
246	struct vmbus_chanmsg_hdr chm_hdr;
247	uint32_t	chm_chanid;
248	uint32_t	chm_openid;
249	uint32_t	chm_status;
250} __packed;
251
252/* VMBUS_CHANMSG_TYPE_GPADL_CONN */
253struct vmbus_chanmsg_gpadl_conn {
254	struct vmbus_chanmsg_hdr chm_hdr;
255	uint32_t	chm_chanid;
256	uint32_t	chm_gpadl;
257	uint16_t	chm_range_len;
258	uint16_t	chm_range_cnt;
259	struct vmbus_gpa_range chm_range;
260} __packed;
261
262#define VMBUS_CHANMSG_GPADL_CONN_PGMAX		26
263CTASSERT(__offsetof(struct vmbus_chanmsg_gpadl_conn,
264    chm_range.gpa_page[VMBUS_CHANMSG_GPADL_CONN_PGMAX]) <=
265    HYPERCALL_POSTMSGIN_DSIZE_MAX);
266
267/* VMBUS_CHANMSG_TYPE_GPADL_SUBCONN */
268struct vmbus_chanmsg_gpadl_subconn {
269	struct vmbus_chanmsg_hdr chm_hdr;
270	uint32_t	chm_msgno;
271	uint32_t	chm_gpadl;
272	uint64_t	chm_gpa_page[];
273} __packed;
274
275#define VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX	28
276CTASSERT(__offsetof(struct vmbus_chanmsg_gpadl_subconn,
277    chm_gpa_page[VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX]) <=
278    HYPERCALL_POSTMSGIN_DSIZE_MAX);
279
280/* VMBUS_CHANMSG_TYPE_GPADL_CONNRESP */
281struct vmbus_chanmsg_gpadl_connresp {
282	struct vmbus_chanmsg_hdr chm_hdr;
283	uint32_t	chm_chanid;
284	uint32_t	chm_gpadl;
285	uint32_t	chm_status;
286} __packed;
287
288/* VMBUS_CHANMSG_TYPE_CHCLOSE */
289struct vmbus_chanmsg_chclose {
290	struct vmbus_chanmsg_hdr chm_hdr;
291	uint32_t	chm_chanid;
292} __packed;
293
294/* VMBUS_CHANMSG_TYPE_GPADL_DISCONN */
295struct vmbus_chanmsg_gpadl_disconn {
296	struct vmbus_chanmsg_hdr chm_hdr;
297	uint32_t	chm_chanid;
298	uint32_t	chm_gpadl;
299} __packed;
300
301/* VMBUS_CHANMSG_TYPE_CHFREE */
302struct vmbus_chanmsg_chfree {
303	struct vmbus_chanmsg_hdr chm_hdr;
304	uint32_t	chm_chanid;
305} __packed;
306
307/* VMBUS_CHANMSG_TYPE_CHRESCIND */
308struct vmbus_chanmsg_chrescind {
309	struct vmbus_chanmsg_hdr chm_hdr;
310	uint32_t	chm_chanid;
311} __packed;
312
313/* VMBUS_CHANMSG_TYPE_CHOFFER */
314struct vmbus_chanmsg_choffer {
315	struct vmbus_chanmsg_hdr chm_hdr;
316	struct hyperv_guid chm_chtype;
317	struct hyperv_guid chm_chinst;
318	uint64_t	chm_chlat;	/* unit: 100ns */
319	uint32_t	chm_chrev;
320	uint32_t	chm_svrctx_sz;
321	uint16_t	chm_chflags;
322	uint16_t	chm_mmio_sz;	/* unit: MB */
323	uint8_t		chm_udata[120];
324	uint16_t	chm_subidx;
325	uint16_t	chm_rsvd;
326	uint32_t	chm_chanid;
327	uint8_t		chm_montrig;
328	uint8_t		chm_flags1;	/* VMBUS_CHOFFER_FLAG1_ */
329	uint16_t	chm_flags2;
330	uint32_t	chm_connid;
331} __packed;
332CTASSERT(sizeof(struct vmbus_chanmsg_choffer) <= VMBUS_MSG_DSIZE_MAX);
333
334#define VMBUS_CHOFFER_FLAG1_HASMNF	0x01
335
336#endif	/* !_VMBUS_REG_H_ */
337