1301019Ssephe/*-
2301019Ssephe * Copyright (c) 2016 Microsoft Corp.
3301019Ssephe * All rights reserved.
4301019Ssephe *
5301019Ssephe * Redistribution and use in source and binary forms, with or without
6301019Ssephe * modification, are permitted provided that the following conditions
7301019Ssephe * are met:
8301019Ssephe * 1. Redistributions of source code must retain the above copyright
9301019Ssephe *    notice unmodified, this list of conditions, and the following
10301019Ssephe *    disclaimer.
11301019Ssephe * 2. Redistributions in binary form must reproduce the above copyright
12301019Ssephe *    notice, this list of conditions and the following disclaimer in the
13301019Ssephe *    documentation and/or other materials provided with the distribution.
14301019Ssephe *
15301019Ssephe * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16301019Ssephe * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17301019Ssephe * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18301019Ssephe * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19301019Ssephe * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20301019Ssephe * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21301019Ssephe * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22301019Ssephe * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23301019Ssephe * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24301019Ssephe * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25301019Ssephe *
26301019Ssephe * $FreeBSD: stable/11/sys/dev/hyperv/vmbus/vmbus_reg.h 307498 2016-10-17 08:10:24Z sephe $
27301019Ssephe */
28301019Ssephe
29301019Ssephe#ifndef _VMBUS_REG_H_
30301019Ssephe#define _VMBUS_REG_H_
31301019Ssephe
32301019Ssephe#include <sys/param.h>
33307455Ssephe#include <dev/hyperv/include/hyperv.h> /* XXX for hyperv_guid */
34307455Ssephe#include <dev/hyperv/include/vmbus.h>
35307301Ssephe#include <dev/hyperv/vmbus/hyperv_reg.h>
36301019Ssephe
37301019Ssephe/*
38301019Ssephe * Hyper-V SynIC message format.
39301019Ssephe */
40301019Ssephe
41301019Ssephe#define VMBUS_MSG_DSIZE_MAX		240
42301019Ssephe#define VMBUS_MSG_SIZE			256
43301019Ssephe
44301019Ssephestruct vmbus_message {
45307278Ssephe	uint32_t	msg_type;	/* HYPERV_MSGTYPE_ */
46301019Ssephe	uint8_t		msg_dsize;	/* data size */
47301019Ssephe	uint8_t		msg_flags;	/* VMBUS_MSGFLAG_ */
48301019Ssephe	uint16_t	msg_rsvd;
49301019Ssephe	uint64_t	msg_id;
50301019Ssephe	uint8_t		msg_data[VMBUS_MSG_DSIZE_MAX];
51301019Ssephe} __packed;
52301019SsepheCTASSERT(sizeof(struct vmbus_message) == VMBUS_MSG_SIZE);
53301019Ssephe
54301019Ssephe#define VMBUS_MSGFLAG_PENDING		0x01
55301019Ssephe
56301106Ssephe/*
57301106Ssephe * Hyper-V SynIC event flags
58301106Ssephe */
59301106Ssephe
60301106Ssephe#ifdef __LP64__
61301106Ssephe#define VMBUS_EVTFLAGS_MAX	32
62301106Ssephe#define VMBUS_EVTFLAG_SHIFT	6
63301106Ssephe#else
64301106Ssephe#define VMBUS_EVTFLAGS_MAX	64
65301106Ssephe#define VMBUS_EVTFLAG_SHIFT	5
66301106Ssephe#endif
67301106Ssephe#define VMBUS_EVTFLAG_LEN	(1 << VMBUS_EVTFLAG_SHIFT)
68301588Ssephe#define VMBUS_EVTFLAG_MASK	(VMBUS_EVTFLAG_LEN - 1)
69301106Ssephe#define VMBUS_EVTFLAGS_SIZE	256
70301106Ssephe
71301106Ssephestruct vmbus_evtflags {
72301106Ssephe	u_long		evt_flags[VMBUS_EVTFLAGS_MAX];
73301106Ssephe} __packed;
74301106SsepheCTASSERT(sizeof(struct vmbus_evtflags) == VMBUS_EVTFLAGS_SIZE);
75301106Ssephe
76301106Ssephe/*
77307310Ssephe * Hyper-V Monitor Notification Facility
78307310Ssephe */
79307310Ssephe
80307310Ssephestruct vmbus_mon_trig {
81307310Ssephe	uint32_t	mt_pending;
82307310Ssephe	uint32_t	mt_armed;
83307310Ssephe} __packed;
84307310Ssephe
85307310Ssephe#define VMBUS_MONTRIGS_MAX	4
86307310Ssephe#define VMBUS_MONTRIG_LEN	32
87307310Ssephe
88307310Ssephestruct vmbus_mnf {
89307310Ssephe	uint32_t	mnf_state;
90307310Ssephe	uint32_t	mnf_rsvd1;
91307310Ssephe
92307310Ssephe	struct vmbus_mon_trig mnf_trigs[VMBUS_MONTRIGS_MAX];
93307310Ssephe	uint8_t		mnf_rsvd2[536];
94307310Ssephe
95307310Ssephe	uint16_t	mnf_lat[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN];
96307310Ssephe	uint8_t		mnf_rsvd3[256];
97307310Ssephe
98307310Ssephe	struct hyperv_mon_param
99307310Ssephe			mnf_param[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN];
100307310Ssephe	uint8_t		mnf_rsvd4[1984];
101307310Ssephe} __packed;
102307310SsepheCTASSERT(sizeof(struct vmbus_mnf) == PAGE_SIZE);
103307310Ssephe
104307310Ssephe/*
105307462Ssephe * Buffer ring
106307462Ssephe */
107307462Ssephestruct vmbus_bufring {
108307462Ssephe	/*
109307462Ssephe	 * If br_windex == br_rindex, this bufring is empty; this
110307462Ssephe	 * means we can _not_ write data to the bufring, if the
111307462Ssephe	 * write is going to make br_windex same as br_rindex.
112307462Ssephe	 */
113307462Ssephe	volatile uint32_t	br_windex;
114307462Ssephe	volatile uint32_t	br_rindex;
115307462Ssephe
116307462Ssephe	/*
117307462Ssephe	 * Interrupt mask {0,1}
118307462Ssephe	 *
119307462Ssephe	 * For TX bufring, host set this to 1, when it is processing
120307462Ssephe	 * the TX bufring, so that we can safely skip the TX event
121307462Ssephe	 * notification to host.
122307462Ssephe	 *
123307462Ssephe	 * For RX bufring, once this is set to 1 by us, host will not
124307462Ssephe	 * further dispatch interrupts to us, even if there are data
125307462Ssephe	 * pending on the RX bufring.  This effectively disables the
126307462Ssephe	 * interrupt of the channel to which this RX bufring is attached.
127307462Ssephe	 */
128307462Ssephe	volatile uint32_t	br_imask;
129307462Ssephe
130307462Ssephe	uint8_t			br_rsvd[4084];
131307462Ssephe	uint8_t			br_data[];
132307462Ssephe} __packed;
133307462SsepheCTASSERT(sizeof(struct vmbus_bufring) == PAGE_SIZE);
134307462Ssephe
135307462Ssephe/*
136301106Ssephe * Channel
137301106Ssephe */
138301106Ssephe
139301106Ssephe#define VMBUS_CHAN_MAX_COMPAT	256
140301106Ssephe#define VMBUS_CHAN_MAX		(VMBUS_EVTFLAG_LEN * VMBUS_EVTFLAGS_MAX)
141301106Ssephe
142307278Ssephe/*
143307455Ssephe * Channel packets
144307301Ssephe */
145307455Ssephe
146307455Ssephe#define VMBUS_CHANPKT_SIZE_ALIGN	(1 << VMBUS_CHANPKT_SIZE_SHIFT)
147307455Ssephe
148307456Ssephe#define VMBUS_CHANPKT_SETLEN(pktlen, len)		\
149307456Ssephedo {							\
150307456Ssephe	(pktlen) = (len) >> VMBUS_CHANPKT_SIZE_SHIFT;	\
151307456Ssephe} while (0)
152307456Ssephe
153307456Ssephe#define VMBUS_CHANPKT_TOTLEN(tlen)	\
154307456Ssephe	roundup2((tlen), VMBUS_CHANPKT_SIZE_ALIGN)
155307456Ssephe
156307498Ssephe#define VMBUS_CHANPKT_HLEN_MIN		\
157307498Ssephe	(sizeof(struct vmbus_chanpkt_hdr) >> VMBUS_CHANPKT_SIZE_SHIFT)
158307498Ssephe
159307455Ssephestruct vmbus_chanpkt {
160307455Ssephe	struct vmbus_chanpkt_hdr cp_hdr;
161307455Ssephe} __packed;
162307455Ssephe
163307455Ssephestruct vmbus_chanpkt_sglist {
164307455Ssephe	struct vmbus_chanpkt_hdr cp_hdr;
165307455Ssephe	uint32_t	cp_rsvd;
166307455Ssephe	uint32_t	cp_gpa_cnt;
167307455Ssephe	struct vmbus_gpa cp_gpa[];
168307455Ssephe} __packed;
169307455Ssephe
170307455Ssephestruct vmbus_chanpkt_prplist {
171307455Ssephe	struct vmbus_chanpkt_hdr cp_hdr;
172307455Ssephe	uint32_t	cp_rsvd;
173307455Ssephe	uint32_t	cp_range_cnt;
174307455Ssephe	struct vmbus_gpa_range cp_range[];
175307455Ssephe} __packed;
176307455Ssephe
177307301Ssephe/*
178307278Ssephe * Channel messages
179307448Ssephe * - Embedded in vmbus_message.msg_data, e.g. response and notification.
180307278Ssephe * - Embedded in hypercall_postmsg_in.hc_data, e.g. request.
181307278Ssephe */
182307278Ssephe
183307448Ssephe#define VMBUS_CHANMSG_TYPE_CHOFFER		1	/* NOTE */
184307448Ssephe#define VMBUS_CHANMSG_TYPE_CHRESCIND		2	/* NOTE */
185307302Ssephe#define VMBUS_CHANMSG_TYPE_CHREQUEST		3	/* REQ */
186307448Ssephe#define VMBUS_CHANMSG_TYPE_CHOFFER_DONE		4	/* NOTE */
187307301Ssephe#define VMBUS_CHANMSG_TYPE_CHOPEN		5	/* REQ */
188307301Ssephe#define VMBUS_CHANMSG_TYPE_CHOPEN_RESP		6	/* RESP */
189307301Ssephe#define VMBUS_CHANMSG_TYPE_CHCLOSE		7	/* REQ */
190307301Ssephe#define VMBUS_CHANMSG_TYPE_GPADL_CONN		8	/* REQ */
191307301Ssephe#define VMBUS_CHANMSG_TYPE_GPADL_SUBCONN	9	/* REQ */
192307301Ssephe#define VMBUS_CHANMSG_TYPE_GPADL_CONNRESP	10	/* RESP */
193307301Ssephe#define VMBUS_CHANMSG_TYPE_GPADL_DISCONN	11	/* REQ */
194307301Ssephe#define VMBUS_CHANMSG_TYPE_GPADL_DISCONNRESP	12	/* RESP */
195307303Ssephe#define VMBUS_CHANMSG_TYPE_CHFREE		13	/* REQ */
196307302Ssephe#define VMBUS_CHANMSG_TYPE_CONNECT		14	/* REQ */
197307302Ssephe#define VMBUS_CHANMSG_TYPE_CONNECT_RESP		15	/* RESP */
198307302Ssephe#define VMBUS_CHANMSG_TYPE_DISCONNECT		16	/* REQ */
199307448Ssephe#define VMBUS_CHANMSG_TYPE_MAX			22
200307278Ssephe
201307278Ssephestruct vmbus_chanmsg_hdr {
202307278Ssephe	uint32_t	chm_type;	/* VMBUS_CHANMSG_TYPE_ */
203307278Ssephe	uint32_t	chm_rsvd;
204307278Ssephe} __packed;
205307278Ssephe
206307302Ssephe/* VMBUS_CHANMSG_TYPE_CONNECT */
207307302Ssephestruct vmbus_chanmsg_connect {
208307278Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
209307278Ssephe	uint32_t	chm_ver;
210307278Ssephe	uint32_t	chm_rsvd;
211307278Ssephe	uint64_t	chm_evtflags;
212307278Ssephe	uint64_t	chm_mnf1;
213307278Ssephe	uint64_t	chm_mnf2;
214307278Ssephe} __packed;
215307278Ssephe
216307302Ssephe/* VMBUS_CHANMSG_TYPE_CONNECT_RESP */
217307302Ssephestruct vmbus_chanmsg_connect_resp {
218307278Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
219307302Ssephe	uint8_t		chm_done;
220307278Ssephe} __packed;
221307278Ssephe
222307302Ssephe/* VMBUS_CHANMSG_TYPE_CHREQUEST */
223307302Ssephestruct vmbus_chanmsg_chrequest {
224307291Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
225307291Ssephe} __packed;
226307291Ssephe
227307302Ssephe/* VMBUS_CHANMSG_TYPE_DISCONNECT */
228307302Ssephestruct vmbus_chanmsg_disconnect {
229307291Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
230307291Ssephe} __packed;
231307291Ssephe
232307301Ssephe/* VMBUS_CHANMSG_TYPE_CHOPEN */
233307301Ssephestruct vmbus_chanmsg_chopen {
234307301Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
235307301Ssephe	uint32_t	chm_chanid;
236307301Ssephe	uint32_t	chm_openid;
237307301Ssephe	uint32_t	chm_gpadl;
238307301Ssephe	uint32_t	chm_vcpuid;
239307459Ssephe	uint32_t	chm_txbr_pgcnt;
240307301Ssephe#define VMBUS_CHANMSG_CHOPEN_UDATA_SIZE	120
241307301Ssephe	uint8_t		chm_udata[VMBUS_CHANMSG_CHOPEN_UDATA_SIZE];
242307301Ssephe} __packed;
243307301Ssephe
244307301Ssephe/* VMBUS_CHANMSG_TYPE_CHOPEN_RESP */
245307301Ssephestruct vmbus_chanmsg_chopen_resp {
246307301Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
247307301Ssephe	uint32_t	chm_chanid;
248307301Ssephe	uint32_t	chm_openid;
249307301Ssephe	uint32_t	chm_status;
250307301Ssephe} __packed;
251307301Ssephe
252307301Ssephe/* VMBUS_CHANMSG_TYPE_GPADL_CONN */
253307301Ssephestruct vmbus_chanmsg_gpadl_conn {
254307301Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
255307301Ssephe	uint32_t	chm_chanid;
256307301Ssephe	uint32_t	chm_gpadl;
257307301Ssephe	uint16_t	chm_range_len;
258307301Ssephe	uint16_t	chm_range_cnt;
259307301Ssephe	struct vmbus_gpa_range chm_range;
260307301Ssephe} __packed;
261307301Ssephe
262307301Ssephe#define VMBUS_CHANMSG_GPADL_CONN_PGMAX		26
263307301SsepheCTASSERT(__offsetof(struct vmbus_chanmsg_gpadl_conn,
264307301Ssephe    chm_range.gpa_page[VMBUS_CHANMSG_GPADL_CONN_PGMAX]) <=
265307301Ssephe    HYPERCALL_POSTMSGIN_DSIZE_MAX);
266307301Ssephe
267307301Ssephe/* VMBUS_CHANMSG_TYPE_GPADL_SUBCONN */
268307301Ssephestruct vmbus_chanmsg_gpadl_subconn {
269307301Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
270307301Ssephe	uint32_t	chm_msgno;
271307301Ssephe	uint32_t	chm_gpadl;
272307301Ssephe	uint64_t	chm_gpa_page[];
273307301Ssephe} __packed;
274307301Ssephe
275307301Ssephe#define VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX	28
276307301SsepheCTASSERT(__offsetof(struct vmbus_chanmsg_gpadl_subconn,
277307301Ssephe    chm_gpa_page[VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX]) <=
278307301Ssephe    HYPERCALL_POSTMSGIN_DSIZE_MAX);
279307301Ssephe
280307301Ssephe/* VMBUS_CHANMSG_TYPE_GPADL_CONNRESP */
281307301Ssephestruct vmbus_chanmsg_gpadl_connresp {
282307301Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
283307301Ssephe	uint32_t	chm_chanid;
284307301Ssephe	uint32_t	chm_gpadl;
285307301Ssephe	uint32_t	chm_status;
286307301Ssephe} __packed;
287307301Ssephe
288307301Ssephe/* VMBUS_CHANMSG_TYPE_CHCLOSE */
289307301Ssephestruct vmbus_chanmsg_chclose {
290307301Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
291307301Ssephe	uint32_t	chm_chanid;
292307301Ssephe} __packed;
293307301Ssephe
294307301Ssephe/* VMBUS_CHANMSG_TYPE_GPADL_DISCONN */
295307301Ssephestruct vmbus_chanmsg_gpadl_disconn {
296307301Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
297307301Ssephe	uint32_t	chm_chanid;
298307301Ssephe	uint32_t	chm_gpadl;
299307301Ssephe} __packed;
300307301Ssephe
301307303Ssephe/* VMBUS_CHANMSG_TYPE_CHFREE */
302307303Ssephestruct vmbus_chanmsg_chfree {
303307303Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
304307303Ssephe	uint32_t	chm_chanid;
305307303Ssephe} __packed;
306307303Ssephe
307307448Ssephe/* VMBUS_CHANMSG_TYPE_CHRESCIND */
308307448Ssephestruct vmbus_chanmsg_chrescind {
309307448Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
310307448Ssephe	uint32_t	chm_chanid;
311307448Ssephe} __packed;
312307448Ssephe
313307448Ssephe/* VMBUS_CHANMSG_TYPE_CHOFFER */
314307448Ssephestruct vmbus_chanmsg_choffer {
315307448Ssephe	struct vmbus_chanmsg_hdr chm_hdr;
316307448Ssephe	struct hyperv_guid chm_chtype;
317307448Ssephe	struct hyperv_guid chm_chinst;
318307448Ssephe	uint64_t	chm_chlat;	/* unit: 100ns */
319307448Ssephe	uint32_t	chm_chrev;
320307448Ssephe	uint32_t	chm_svrctx_sz;
321307448Ssephe	uint16_t	chm_chflags;
322307448Ssephe	uint16_t	chm_mmio_sz;	/* unit: MB */
323307448Ssephe	uint8_t		chm_udata[120];
324307448Ssephe	uint16_t	chm_subidx;
325307448Ssephe	uint16_t	chm_rsvd;
326307448Ssephe	uint32_t	chm_chanid;
327307448Ssephe	uint8_t		chm_montrig;
328307448Ssephe	uint8_t		chm_flags1;	/* VMBUS_CHOFFER_FLAG1_ */
329307448Ssephe	uint16_t	chm_flags2;
330307448Ssephe	uint32_t	chm_connid;
331307448Ssephe} __packed;
332307448SsepheCTASSERT(sizeof(struct vmbus_chanmsg_choffer) <= VMBUS_MSG_DSIZE_MAX);
333307448Ssephe
334307448Ssephe#define VMBUS_CHOFFER_FLAG1_HASMNF	0x01
335307448Ssephe
336301019Ssephe#endif	/* !_VMBUS_REG_H_ */
337