]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/hyperv/include/hyperv.h
hyperv/vmbus: Deprecate the device private data in channel struct
[FreeBSD/FreeBSD.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 /*
62  * VMBUS version is 32 bit, upper 16 bit for major_number and lower
63  * 16 bit for minor_number.
64  *
65  * 0.13  --  Windows Server 2008
66  * 1.1   --  Windows 7
67  * 2.4   --  Windows 8
68  * 3.0   --  Windows 8.1
69  */
70 #define VMBUS_VERSION_WS2008            ((0 << 16) | (13))
71 #define VMBUS_VERSION_WIN7              ((1 << 16) | (1))
72 #define VMBUS_VERSION_WIN8              ((2 << 16) | (4))
73 #define VMBUS_VERSION_WIN8_1            ((3 << 16) | (0))
74
75 #define VMBUS_VERSION_MAJOR(ver)        (((uint32_t)(ver)) >> 16)
76 #define VMBUS_VERSION_MINOR(ver)        (((uint32_t)(ver)) & 0xffff)
77
78 struct hyperv_guid {
79         uint8_t         hv_guid[16];
80 } __packed;
81
82 #define HYPERV_GUID_STRLEN      40
83
84 int     hyperv_guid2str(const struct hyperv_guid *, char *, size_t);
85
86 typedef struct {
87         /*
88          * offset in bytes from the start of ring data below
89          */
90         volatile uint32_t       write_index;
91         /*
92          * offset in bytes from the start of ring data below
93          */
94         volatile uint32_t       read_index;
95         /*
96          * NOTE: The interrupt_mask field is used only for channels, but
97          * vmbus connection also uses this data structure
98          */
99         volatile uint32_t       interrupt_mask;
100         /* pad it to PAGE_SIZE so that data starts on a page */
101         uint8_t                 reserved[4084];
102
103         /*
104          * WARNING: Ring data starts here
105          *  !!! DO NOT place any fields below this !!!
106          */
107         uint8_t                 buffer[0];      /* doubles as interrupt mask */
108 } __packed hv_vmbus_ring_buffer;
109
110 typedef struct {
111         hv_vmbus_ring_buffer*   ring_buffer;
112         struct mtx              ring_lock;
113         uint32_t                ring_data_size; /* ring_size */
114 } hv_vmbus_ring_buffer_info;
115
116 struct hv_vmbus_channel;
117
118 typedef void    (*vmbus_chan_callback_t)(struct hv_vmbus_channel *, void *);
119
120 typedef struct hv_vmbus_channel {
121         device_t                        ch_dev;
122         struct vmbus_softc              *ch_vmbus;
123         uint32_t                        ch_flags;       /* VMBUS_CHAN_FLAG_ */
124         uint32_t                        ch_id;          /* channel id */
125
126         /*
127          * These are based on the offer_msg.monitor_id.
128          * Save it here for easy access.
129          */
130         int                             ch_montrig_idx; /* MNF trig index */
131         uint32_t                        ch_montrig_mask;/* MNF trig mask */
132
133         /*
134          * TX bufring; at the beginning of ch_bufring.
135          */
136         hv_vmbus_ring_buffer_info       ch_txbr;
137         /*
138          * RX bufring; immediately following ch_txbr.
139          */
140         hv_vmbus_ring_buffer_info       ch_rxbr;
141
142         struct taskqueue                *ch_tq;
143         struct task                     ch_task;
144         vmbus_chan_callback_t           ch_cb;
145         void                            *ch_cbarg;
146
147         struct hyperv_mon_param         *ch_monprm;
148         struct hyperv_dma               ch_monprm_dma;
149
150         int                             ch_cpuid;       /* owner cpu */
151         /*
152          * Virtual cpuid for ch_cpuid; it is used to communicate cpuid
153          * related information w/ Hyper-V.  If MSR_HV_VP_INDEX does not
154          * exist, ch_vcpuid will always be 0 for compatibility.
155          */
156         uint32_t                        ch_vcpuid;
157
158         /*
159          * If this is a primary channel, ch_subchan* fields
160          * contain sub-channels belonging to this primary
161          * channel.
162          */
163         struct mtx                      ch_subchan_lock;
164         TAILQ_HEAD(, hv_vmbus_channel)  ch_subchans;
165         int                             ch_subchan_cnt;
166
167         /* If this is a sub-channel */
168         TAILQ_ENTRY(hv_vmbus_channel)   ch_sublink;     /* sub-channel link */
169         struct hv_vmbus_channel         *ch_prichan;    /* owner primary chan */
170
171         void                            *ch_bufring;    /* TX+RX bufrings */
172         struct hyperv_dma               ch_bufring_dma;
173         uint32_t                        ch_bufring_gpadl;
174
175         struct task                     ch_detach_task;
176         TAILQ_ENTRY(hv_vmbus_channel)   ch_prilink;     /* primary chan link */
177         uint32_t                        ch_subidx;      /* subchan index */
178         volatile uint32_t               ch_stflags;     /* atomic-op */
179                                                         /* VMBUS_CHAN_ST_ */
180         struct hyperv_guid              ch_guid_type;
181         struct hyperv_guid              ch_guid_inst;
182
183         struct sysctl_ctx_list          ch_sysctl_ctx;
184 } hv_vmbus_channel;
185
186 #define VMBUS_CHAN_ISPRIMARY(chan)      ((chan)->ch_subidx == 0)
187
188 #define VMBUS_CHAN_FLAG_HASMNF          0x0001
189 /*
190  * If this flag is set, this channel's interrupt will be masked in ISR,
191  * and the RX bufring will be drained before this channel's interrupt is
192  * unmasked.
193  *
194  * This flag is turned on by default.  Drivers can turn it off according
195  * to their own requirement.
196  */
197 #define VMBUS_CHAN_FLAG_BATCHREAD       0x0002
198
199 #define VMBUS_CHAN_ST_OPENED_SHIFT      0
200 #define VMBUS_CHAN_ST_OPENED            (1 << VMBUS_CHAN_ST_OPENED_SHIFT)
201
202 /**
203  * @brief Get physical address from virtual
204  */
205 static inline unsigned long
206 hv_get_phys_addr(void *virt)
207 {
208         unsigned long ret;
209         ret = (vtophys(virt) | ((vm_offset_t) virt & PAGE_MASK));
210         return (ret);
211 }
212
213 static __inline struct hv_vmbus_channel *
214 vmbus_get_channel(device_t dev)
215 {
216         return device_get_ivars(dev);
217 }
218
219 #endif  /* __HYPERV_H__ */