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_ */
Cache object: 8f14161e7b85841503185a21f8465532
|