xref: /openbsd/sys/dev/pv/hypervvar.h (revision 4cfece93)
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 clear_bit(u_int b, volatile void *p)
167 {
168 	atomic_clearbits_int(((volatile u_int *)p) + (b >> 5), 1 << (b & 0x1f));
169 }
170 
171 static __inline void
172 set_bit(u_int b, volatile void *p)
173 {
174 	atomic_setbits_int(((volatile u_int *)p) + (b >> 5), 1 << (b & 0x1f));
175 }
176 
177 static __inline int
178 test_bit(u_int b, volatile void *p)
179 {
180 	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_ */
225