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_ */ 433