1 /*
2  *
3  * Copyright (c) 2009, Microsoft Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16  * Place - Suite 330, Boston, MA 02111-1307 USA.
17  *
18  * Authors:
19  *   Haiyang Zhang <haiyangz@microsoft.com>
20  *   Hank Janssen  <hjanssen@microsoft.com>
21  *
22  */
23 
24 #ifndef _VMBUSPACKETFORMAT_H_
25 #define _VMBUSPACKETFORMAT_H_
26 
27 struct vmpacket_descriptor {
28 	u16 type;
29 	u16 offset8;
30 	u16 len8;
31 	u16 flags;
32 	u64 trans_id;
33 } __packed;
34 
35 struct vmpacket_header {
36 	u32 prev_pkt_start_offset;
37 	struct vmpacket_descriptor descriptor;
38 } __packed;
39 
40 struct vmtransfer_page_range {
41 	u32 byte_count;
42 	u32 byte_offset;
43 } __packed;
44 
45 struct vmtransfer_page_packet_header {
46 	struct vmpacket_descriptor d;
47 	u16 xfer_pageset_id;
48 	bool sender_owns_set;
49 	u8 reserved;
50 	u32 range_cnt;
51 	struct vmtransfer_page_range ranges[1];
52 } __packed;
53 
54 struct vmgpadl_packet_header {
55 	struct vmpacket_descriptor d;
56 	u32 gpadl;
57 	u32 reserved;
58 } __packed;
59 
60 struct vmadd_remove_transfer_page_set {
61 	struct vmpacket_descriptor d;
62 	u32 gpadl;
63 	u16 xfer_pageset_id;
64 	u16 reserved;
65 } __packed;
66 
67 /*
68  * This structure defines a range in guest physical space that can be made to
69  * look virtually contiguous.
70  */
71 struct gpa_range {
72 	u32 byte_count;
73 	u32 byte_offset;
74 	u64 pfn_array[0];
75 };
76 
77 /*
78  * This is the format for an Establish Gpadl packet, which contains a handle by
79  * which this GPADL will be known and a set of GPA ranges associated with it.
80  * This can be converted to a MDL by the guest OS.  If there are multiple GPA
81  * ranges, then the resulting MDL will be "chained," representing multiple VA
82  * ranges.
83  */
84 struct vmestablish_gpadl {
85 	struct vmpacket_descriptor d;
86 	u32 gpadl;
87 	u32 range_cnt;
88 	struct gpa_range range[1];
89 } __packed;
90 
91 /*
92  * This is the format for a Teardown Gpadl packet, which indicates that the
93  * GPADL handle in the Establish Gpadl packet will never be referenced again.
94  */
95 struct vmteardown_gpadl {
96 	struct vmpacket_descriptor d;
97 	u32 gpadl;
98 	u32 reserved;	/* for alignment to a 8-byte boundary */
99 } __packed;
100 
101 /*
102  * This is the format for a GPA-Direct packet, which contains a set of GPA
103  * ranges, in addition to commands and/or data.
104  */
105 struct vmdata_gpa_direct {
106 	struct vmpacket_descriptor d;
107 	u32 reserved;
108 	u32 range_cnt;
109 	struct gpa_range range[1];
110 } __packed;
111 
112 /* This is the format for a Additional Data Packet. */
113 struct vmadditional_data {
114 	struct vmpacket_descriptor d;
115 	u64 total_bytes;
116 	u32 offset;
117 	u32 byte_cnt;
118 	unsigned char data[1];
119 } __packed;
120 
121 union vmpacket_largest_possible_header {
122 	struct vmpacket_descriptor simple_hdr;
123 	struct vmtransfer_page_packet_header xfer_page_hdr;
124 	struct vmgpadl_packet_header gpadl_hdr;
125 	struct vmadd_remove_transfer_page_set add_rm_xfer_page_hdr;
126 	struct vmestablish_gpadl establish_gpadl_hdr;
127 	struct vmteardown_gpadl teardown_gpadl_hdr;
128 	struct vmdata_gpa_direct data_gpa_direct_hdr;
129 };
130 
131 #define VMPACKET_DATA_START_ADDRESS(__packet)	\
132 	(void *)(((unsigned char *)__packet) +	\
133 	 ((struct vmpacket_descriptor)__packet)->offset8 * 8)
134 
135 #define VMPACKET_DATA_LENGTH(__packet)		\
136 	((((struct vmpacket_descriptor)__packet)->len8 -	\
137 	  ((struct vmpacket_descriptor)__packet)->offset8) * 8)
138 
139 #define VMPACKET_TRANSFER_MODE(__packet)	\
140 	(((struct IMPACT)__packet)->type)
141 
142 enum vmbus_packet_type {
143 	VM_PKT_INVALID				= 0x0,
144 	VM_PKT_SYNCH				= 0x1,
145 	VM_PKT_ADD_XFER_PAGESET			= 0x2,
146 	VM_PKT_RM_XFER_PAGESET			= 0x3,
147 	VM_PKT_ESTABLISH_GPADL			= 0x4,
148 	VM_PKT_TEARDOWN_GPADL			= 0x5,
149 	VM_PKT_DATA_INBAND			= 0x6,
150 	VM_PKT_DATA_USING_XFER_PAGES		= 0x7,
151 	VM_PKT_DATA_USING_GPADL			= 0x8,
152 	VM_PKT_DATA_USING_GPA_DIRECT		= 0x9,
153 	VM_PKT_CANCEL_REQUEST			= 0xa,
154 	VM_PKT_COMP				= 0xb,
155 	VM_PKT_DATA_USING_ADDITIONAL_PKT	= 0xc,
156 	VM_PKT_ADDITIONAL_DATA			= 0xd
157 };
158 
159 #define VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED	1
160 
161 #endif
162