Line data Source code
1 : /*
2 : * Copyright (c) 2016 Mike Belopuhov <mike@esdenera.com>
3 : *
4 : * Permission to use, copy, modify, and distribute this software for any
5 : * purpose with or without fee is hereby granted, provided that the above
6 : * copyright notice and this permission notice appear in all copies.
7 : *
8 : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 : */
16 :
17 : #ifndef _DEV_PV_HYPERVVAR_H_
18 : #define _DEV_PV_HYPERVVAR_H_
19 :
20 : /* #define HYPERV_DEBUG */
21 :
22 : #ifdef HYPERV_DEBUG
23 : #define DPRINTF(x...) printf(x)
24 : #else
25 : #define DPRINTF(x...)
26 : #endif
27 :
28 : struct hv_softc;
29 :
30 : struct hv_msg {
31 : uint64_t msg_flags;
32 : #define MSGF_NOSLEEP 0x0001
33 : #define MSGF_NOQUEUE 0x0002
34 : #define MSGF_ORPHANED 0x0004
35 : struct hypercall_postmsg_in msg_req; /* must be 8 byte aligned */
36 : void *msg_rsp;
37 : size_t msg_rsplen;
38 : TAILQ_ENTRY(hv_msg) msg_entry;
39 : };
40 : TAILQ_HEAD(hv_queue, hv_msg);
41 :
42 : struct hv_offer {
43 : struct vmbus_chanmsg_choffer co_chan;
44 : SIMPLEQ_ENTRY(hv_offer) co_entry;
45 : };
46 : SIMPLEQ_HEAD(hv_offers, hv_offer);
47 :
48 : struct hv_ring_data {
49 : struct vmbus_bufring *rd_ring;
50 : uint32_t rd_size;
51 : struct mutex rd_lock;
52 : uint32_t rd_prod;
53 : uint32_t rd_cons;
54 : uint32_t rd_dsize;
55 : };
56 :
57 : struct hv_channel {
58 : struct hv_softc *ch_sc;
59 :
60 : int ch_state;
61 : #define HV_CHANSTATE_OFFERED 1
62 : #define HV_CHANSTATE_OPENED 2
63 : #define HV_CHANSTATE_CLOSING 3
64 : #define HV_CHANSTATE_CLOSED 4
65 : uint32_t ch_id;
66 :
67 : struct hv_guid ch_type;
68 : struct hv_guid ch_inst;
69 : char ch_ident[38];
70 :
71 : void *ch_ring;
72 : uint32_t ch_ring_gpadl;
73 : u_long ch_ring_size;
74 :
75 : struct hv_ring_data ch_wrd;
76 : struct hv_ring_data ch_rrd;
77 :
78 : uint32_t ch_vcpu;
79 :
80 : void (*ch_handler)(void *);
81 : void *ch_ctx;
82 : struct evcount ch_evcnt;
83 : struct taskq *ch_taskq;
84 : struct task ch_task;
85 :
86 : uint32_t ch_flags;
87 : #define CHF_BATCHED 0x0001
88 : #define CHF_MONITOR 0x0002
89 :
90 : uint8_t ch_mgroup;
91 : uint8_t ch_mindex;
92 : struct hv_mon_param ch_monprm __attribute__((aligned(8)));
93 :
94 : TAILQ_ENTRY(hv_channel) ch_entry;
95 : };
96 : TAILQ_HEAD(hv_channels, hv_channel);
97 :
98 : struct hv_attach_args {
99 : void *aa_parent;
100 : bus_dma_tag_t aa_dmat;
101 : struct hv_guid *aa_type;
102 : struct hv_guid *aa_inst;
103 : char *aa_ident;
104 : struct hv_channel *aa_chan;
105 : };
106 :
107 : struct hv_dev {
108 : struct hv_attach_args dv_aa;
109 : SLIST_ENTRY(hv_dev) dv_entry;
110 : };
111 : SLIST_HEAD(hv_devices, hv_dev);
112 :
113 : struct hv_softc {
114 : struct device sc_dev;
115 : struct pvbus_hv *sc_pvbus;
116 : struct bus_dma_tag *sc_dmat;
117 :
118 : void *sc_hc;
119 : uint32_t sc_features;
120 :
121 : uint32_t sc_flags;
122 : #define HSF_CONNECTED 0x0001
123 : #define HSF_OFFERS_DELIVERED 0x0002
124 :
125 : int sc_idtvec;
126 : int sc_proto;
127 :
128 : /* CPU id to VCPU id mapping */
129 : uint32_t sc_vcpus[1]; /* XXX: per-cpu */
130 : /* Synthetic Interrupt Message Page (SIMP) */
131 : void *sc_simp[1]; /* XXX: per-cpu */
132 : /* Synthetic Interrupt Event Flags Page (SIEFP) */
133 : void *sc_siep[1]; /* XXX: per-cpu */
134 :
135 : /* Channel port events page */
136 : void *sc_events;
137 : u_long *sc_wevents; /* Write events */
138 : u_long *sc_revents; /* Read events */
139 :
140 : /* Monitor pages for parent<->child notifications */
141 : struct vmbus_mnf *sc_monitor[2];
142 :
143 : struct hv_queue sc_reqs; /* Request queue */
144 : struct mutex sc_reqlck;
145 : struct hv_queue sc_rsps; /* Response queue */
146 : struct mutex sc_rsplck;
147 :
148 : struct hv_offers sc_offers;
149 : struct mutex sc_offerlck;
150 :
151 : struct hv_channels sc_channels;
152 : struct mutex sc_channelck;
153 :
154 : volatile uint32_t sc_handle;
155 :
156 : struct hv_devices sc_devs;
157 : struct mutex sc_devlck;
158 :
159 : struct task sc_sdtask; /* shutdown */
160 :
161 : struct ksensordev sc_sensordev;
162 : struct ksensor sc_sensor;
163 : };
164 :
165 : static __inline void
166 0 : clear_bit(u_int b, volatile void *p)
167 : {
168 0 : atomic_clearbits_int(((volatile u_int *)p) + (b >> 5), 1 << (b & 0x1f));
169 0 : }
170 :
171 : static __inline void
172 0 : set_bit(u_int b, volatile void *p)
173 : {
174 0 : atomic_setbits_int(((volatile u_int *)p) + (b >> 5), 1 << (b & 0x1f));
175 0 : }
176 :
177 : static __inline int
178 0 : test_bit(u_int b, volatile void *p)
179 : {
180 0 : return !!(((volatile u_int *)p)[b >> 5] & (1 << (b & 0x1f)));
181 : }
182 :
183 : extern const struct hv_guid hv_guid_network;
184 : extern const struct hv_guid hv_guid_ide;
185 : extern const struct hv_guid hv_guid_scsi;
186 : extern const struct hv_guid hv_guid_shutdown;
187 : extern const struct hv_guid hv_guid_timesync;
188 : extern const struct hv_guid hv_guid_heartbeat;
189 : extern const struct hv_guid hv_guid_kvp;
190 : #ifdef HYPERV_DEBUG
191 : extern const struct hv_guid hv_guid_vss;
192 : extern const struct hv_guid hv_guid_dynmem;
193 : extern const struct hv_guid hv_guid_mouse;
194 : extern const struct hv_guid hv_guid_kbd;
195 : extern const struct hv_guid hv_guid_video;
196 : extern const struct hv_guid hv_guid_fc;
197 : extern const struct hv_guid hv_guid_fcopy;
198 : extern const struct hv_guid hv_guid_pcie;
199 : extern const struct hv_guid hv_guid_netdir;
200 : extern const struct hv_guid hv_guid_rdesktop;
201 : extern const struct hv_guid hv_guid_avma1;
202 : extern const struct hv_guid hv_guid_avma2;
203 : extern const struct hv_guid hv_guid_avma3;
204 : extern const struct hv_guid hv_guid_avma4;
205 : #endif /* HYPERV_DEBUG */
206 :
207 : int hv_handle_alloc(struct hv_channel *, void *, uint32_t, uint32_t *);
208 : void hv_handle_free(struct hv_channel *, uint32_t);
209 : int hv_channel_open(struct hv_channel *, size_t, void *, size_t,
210 : void (*)(void *), void *);
211 : int hv_channel_close(struct hv_channel *);
212 : int hv_channel_setdeferred(struct hv_channel *, const char *);
213 : void hv_channel_schedule(struct hv_channel *);
214 : void hv_evcount_attach(struct hv_channel *, const char *);
215 : int hv_channel_send(struct hv_channel *, void *, uint32_t, uint64_t,
216 : int, uint32_t);
217 : int hv_channel_send_sgl(struct hv_channel *, struct vmbus_gpa *,
218 : uint32_t, void *, uint32_t, uint64_t);
219 : int hv_channel_send_prpl(struct hv_channel *, struct vmbus_gpa_range *,
220 : uint32_t, void *, uint32_t, uint64_t);
221 : int hv_channel_recv(struct hv_channel *, void *, uint32_t, uint32_t *,
222 : uint64_t *, int);
223 :
224 : #endif /* _DEV_PV_HYPERVVAR_H_ */
|