]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/hyperv/include/hyperv.h
MFC 302882-302884
[FreeBSD/stable/10.git] / sys / dev / hyperv / include / hyperv.h
1 /*-
2  * Copyright (c) 2009-2012,2016 Microsoft Corp.
3  * Copyright (c) 2012 NetApp Inc.
4  * Copyright (c) 2012 Citrix Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30
31 /**
32  * HyperV definitions for messages that are sent between instances of the
33  * Channel Management Library in separate partitions, or in some cases,
34  * back to itself.
35  */
36
37 #ifndef __HYPERV_H__
38 #define __HYPERV_H__
39
40 #include <sys/param.h>
41 #include <sys/mbuf.h>
42 #include <sys/queue.h>
43 #include <sys/malloc.h>
44 #include <sys/kthread.h>
45 #include <sys/taskqueue.h>
46 #include <sys/systm.h>
47 #include <sys/lock.h>
48 #include <sys/sema.h>
49 #include <sys/smp.h>
50 #include <sys/mutex.h>
51 #include <sys/bus.h>
52 #include <sys/sysctl.h>
53 #include <vm/vm.h>
54 #include <vm/vm_param.h>
55 #include <vm/pmap.h>
56
57 #include <amd64/include/xen/synch_bitops.h>
58 #include <amd64/include/atomic.h>
59 #include <dev/hyperv/include/hyperv_busdma.h>
60
61 typedef uint8_t hv_bool_uint8_t;
62
63 #define HV_S_OK                 0x00000000
64 #define HV_E_FAIL               0x80004005
65 #define HV_ERROR_NOT_SUPPORTED  0x80070032
66 #define HV_ERROR_MACHINE_LOCKED 0x800704F7
67
68 /*
69  * VMBUS version is 32 bit, upper 16 bit for major_number and lower
70  * 16 bit for minor_number.
71  *
72  * 0.13  --  Windows Server 2008
73  * 1.1   --  Windows 7
74  * 2.4   --  Windows 8
75  * 3.0   --  Windows 8.1
76  */
77 #define VMBUS_VERSION_WS2008            ((0 << 16) | (13))
78 #define VMBUS_VERSION_WIN7              ((1 << 16) | (1))
79 #define VMBUS_VERSION_WIN8              ((2 << 16) | (4))
80 #define VMBUS_VERSION_WIN8_1            ((3 << 16) | (0))
81
82 #define VMBUS_VERSION_MAJOR(ver)        (((uint32_t)(ver)) >> 16)
83 #define VMBUS_VERSION_MINOR(ver)        (((uint32_t)(ver)) & 0xffff)
84
85 struct hyperv_guid {
86         uint8_t         hv_guid[16];
87 } __packed;
88
89 #define HYPERV_GUID_STRLEN      40
90
91 int     hyperv_guid2str(const struct hyperv_guid *, char *, size_t);
92
93 typedef struct {
94         uint16_t type;
95         uint16_t data_offset8;
96         uint16_t length8;
97         uint16_t flags;
98         uint64_t transaction_id;
99 } __packed hv_vm_packet_descriptor;
100
101 typedef struct {
102         uint32_t byte_count;
103         uint32_t byte_offset;
104 } __packed hv_vm_transfer_page;
105
106 typedef struct {
107         hv_vm_packet_descriptor d;
108         uint16_t                transfer_page_set_id;
109         hv_bool_uint8_t         sender_owns_set;
110         uint8_t                 reserved;
111         uint32_t                range_count;
112         hv_vm_transfer_page     ranges[1];
113 } __packed hv_vm_transfer_page_packet_header;
114
115 #define HW_MACADDR_LEN  6
116
117 /*
118  * Common defines for Hyper-V ICs
119  */
120 #define HV_ICMSGTYPE_NEGOTIATE          0
121 #define HV_ICMSGTYPE_HEARTBEAT          1
122 #define HV_ICMSGTYPE_KVPEXCHANGE        2
123 #define HV_ICMSGTYPE_SHUTDOWN           3
124 #define HV_ICMSGTYPE_TIMESYNC           4
125 #define HV_ICMSGTYPE_VSS                5
126
127 #define HV_ICMSGHDRFLAG_TRANSACTION     1
128 #define HV_ICMSGHDRFLAG_REQUEST         2
129 #define HV_ICMSGHDRFLAG_RESPONSE        4
130
131 typedef struct hv_vmbus_pipe_hdr {
132         uint32_t flags;
133         uint32_t msgsize;
134 } __packed hv_vmbus_pipe_hdr;
135
136 typedef struct hv_vmbus_ic_version {
137         uint16_t major;
138         uint16_t minor;
139 } __packed hv_vmbus_ic_version;
140
141 typedef struct hv_vmbus_icmsg_hdr {
142         hv_vmbus_ic_version     icverframe;
143         uint16_t                icmsgtype;
144         hv_vmbus_ic_version     icvermsg;
145         uint16_t                icmsgsize;
146         uint32_t                status;
147         uint8_t                 ictransaction_id;
148         uint8_t                 icflags;
149         uint8_t                 reserved[2];
150 } __packed hv_vmbus_icmsg_hdr;
151
152 typedef struct hv_vmbus_icmsg_negotiate {
153         uint16_t                icframe_vercnt;
154         uint16_t                icmsg_vercnt;
155         uint32_t                reserved;
156         hv_vmbus_ic_version     icversion_data[1]; /* any size array */
157 } __packed hv_vmbus_icmsg_negotiate;
158
159 typedef struct hv_vmbus_shutdown_msg_data {
160         uint32_t                reason_code;
161         uint32_t                timeout_seconds;
162         uint32_t                flags;
163         uint8_t                 display_message[2048];
164 } __packed hv_vmbus_shutdown_msg_data;
165
166 typedef struct hv_vmbus_heartbeat_msg_data {
167         uint64_t                seq_num;
168         uint32_t                reserved[8];
169 } __packed hv_vmbus_heartbeat_msg_data;
170
171 typedef struct {
172         /*
173          * offset in bytes from the start of ring data below
174          */
175         volatile uint32_t       write_index;
176         /*
177          * offset in bytes from the start of ring data below
178          */
179         volatile uint32_t       read_index;
180         /*
181          * NOTE: The interrupt_mask field is used only for channels, but
182          * vmbus connection also uses this data structure
183          */
184         volatile uint32_t       interrupt_mask;
185         /* pad it to PAGE_SIZE so that data starts on a page */
186         uint8_t                 reserved[4084];
187
188         /*
189          * WARNING: Ring data starts here
190          *  !!! DO NOT place any fields below this !!!
191          */
192         uint8_t                 buffer[0];      /* doubles as interrupt mask */
193 } __packed hv_vmbus_ring_buffer;
194
195 typedef struct {
196         hv_vmbus_ring_buffer*   ring_buffer;
197         struct mtx              ring_lock;
198         uint32_t                ring_data_size; /* ring_size */
199 } hv_vmbus_ring_buffer_info;
200
201 typedef void    (*vmbus_chan_callback_t)(void *);
202
203 typedef struct hv_vmbus_channel {
204         device_t                        ch_dev;
205         struct vmbus_softc              *vmbus_sc;
206         uint32_t                        ch_flags;       /* VMBUS_CHAN_FLAG_ */
207         uint32_t                        ch_id;          /* channel id */
208
209         /*
210          * These are based on the offer_msg.monitor_id.
211          * Save it here for easy access.
212          */
213         int                             ch_montrig_idx; /* MNF trig index */
214         uint32_t                        ch_montrig_mask;/* MNF trig mask */
215
216         /*
217          * send to parent
218          */
219         hv_vmbus_ring_buffer_info       outbound;
220         /*
221          * receive from parent
222          */
223         hv_vmbus_ring_buffer_info       inbound;
224
225         struct taskqueue                *ch_tq;
226         struct task                     ch_task;
227         vmbus_chan_callback_t           ch_cb;
228         void                            *ch_cbarg;
229
230         struct hyperv_mon_param         *ch_monprm;
231         struct hyperv_dma               ch_monprm_dma;
232
233         int                             ch_cpuid;       /* owner cpu */
234         /*
235          * Virtual cpuid for ch_cpuid; it is used to communicate cpuid
236          * related information w/ Hyper-V.  If MSR_HV_VP_INDEX does not
237          * exist, ch_vcpuid will always be 0 for compatibility.
238          */
239         uint32_t                        ch_vcpuid;
240
241         /*
242          * If this is a primary channel, ch_subchan* fields
243          * contain sub-channels belonging to this primary
244          * channel.
245          */
246         struct mtx                      ch_subchan_lock;
247         TAILQ_HEAD(, hv_vmbus_channel)  ch_subchans;
248         int                             ch_subchan_cnt;
249
250         /* If this is a sub-channel */
251         TAILQ_ENTRY(hv_vmbus_channel)   ch_sublink;     /* sub-channel link */
252         struct hv_vmbus_channel         *ch_prichan;    /* owner primary chan */
253
254         /*
255          * Driver private data
256          */
257         void                            *hv_chan_priv1;
258         void                            *hv_chan_priv2;
259         void                            *hv_chan_priv3;
260
261         void                            *ch_bufring;    /* TX+RX bufrings */
262         struct hyperv_dma               ch_bufring_dma;
263         uint32_t                        ch_bufring_gpadl;
264
265         struct task                     ch_detach_task;
266         TAILQ_ENTRY(hv_vmbus_channel)   ch_prilink;     /* primary chan link */
267         uint32_t                        ch_subidx;      /* subchan index */
268         volatile uint32_t               ch_stflags;     /* atomic-op */
269                                                         /* VMBUS_CHAN_ST_ */
270         struct hyperv_guid              ch_guid_type;
271         struct hyperv_guid              ch_guid_inst;
272
273         struct sysctl_ctx_list          ch_sysctl_ctx;
274 } hv_vmbus_channel;
275
276 #define VMBUS_CHAN_ISPRIMARY(chan)      ((chan)->ch_subidx == 0)
277
278 #define VMBUS_CHAN_FLAG_HASMNF          0x0001
279 /*
280  * If this flag is set, this channel's interrupt will be masked in ISR,
281  * and the RX bufring will be drained before this channel's interrupt is
282  * unmasked.
283  *
284  * This flag is turned on by default.  Drivers can turn it off according
285  * to their own requirement.
286  */
287 #define VMBUS_CHAN_FLAG_BATCHREAD       0x0002
288
289 #define VMBUS_CHAN_ST_OPENED_SHIFT      0
290 #define VMBUS_CHAN_ST_OPENED            (1 << VMBUS_CHAN_ST_OPENED_SHIFT)
291
292 static inline void
293 hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t on)
294 {
295         if (!on)
296                 channel->ch_flags &= ~VMBUS_CHAN_FLAG_BATCHREAD;
297         else
298                 channel->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD;
299 }
300
301 int             hv_vmbus_channel_recv_packet(
302                                 hv_vmbus_channel*       channel,
303                                 void*                   buffer,
304                                 uint32_t                buffer_len,
305                                 uint32_t*               buffer_actual_len,
306                                 uint64_t*               request_id);
307
308 int             hv_vmbus_channel_recv_packet_raw(
309                                 hv_vmbus_channel*       channel,
310                                 void*                   buffer,
311                                 uint32_t                buffer_len,
312                                 uint32_t*               buffer_actual_len,
313                                 uint64_t*               request_id);
314
315 int             hv_vmbus_channel_open(
316                                 hv_vmbus_channel*       channel,
317                                 uint32_t                send_ring_buffer_size,
318                                 uint32_t                recv_ring_buffer_size,
319                                 void*                   user_data,
320                                 uint32_t                user_data_len,
321                                 vmbus_chan_callback_t   cb,
322                                 void                    *cbarg);
323
324 void            hv_vmbus_channel_close(hv_vmbus_channel *channel);
325
326 int             hv_vmbus_channel_establish_gpadl(
327                                 hv_vmbus_channel*       channel,
328                                 /* must be phys and virt contiguous */
329                                 void*                   contig_buffer,
330                                 /*  page-size multiple  */
331                                 uint32_t                size,
332                                 uint32_t*               gpadl_handle);
333
334 int             hv_vmbus_channel_teardown_gpdal(
335                                 hv_vmbus_channel*       channel,
336                                 uint32_t                gpadl_handle);
337
338 int             vmbus_chan_gpadl_connect(struct hv_vmbus_channel *chan,
339                     bus_addr_t paddr, int size, uint32_t *gpadl);
340
341 struct hv_vmbus_channel* vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary);
342
343 void            vmbus_channel_cpu_set(struct hv_vmbus_channel *chan, int cpu);
344 void            vmbus_channel_cpu_rr(struct hv_vmbus_channel *chan);
345 struct hv_vmbus_channel **
346                 vmbus_get_subchan(struct hv_vmbus_channel *pri_chan, int subchan_cnt);
347 void            vmbus_rel_subchan(struct hv_vmbus_channel **subchan, int subchan_cnt);
348 void            vmbus_drain_subchan(struct hv_vmbus_channel *pri_chan);
349
350 /**
351  * @brief Get physical address from virtual
352  */
353 static inline unsigned long
354 hv_get_phys_addr(void *virt)
355 {
356         unsigned long ret;
357         ret = (vtophys(virt) | ((vm_offset_t) virt & PAGE_MASK));
358         return (ret);
359 }
360
361 static __inline struct hv_vmbus_channel *
362 vmbus_get_channel(device_t dev)
363 {
364         return device_get_ivars(dev);
365 }
366
367 #endif  /* __HYPERV_H__ */