xref: /openbsd/sys/dev/pv/hypervvar.h (revision 998de4a5)
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 _HYPERVVAR_H_
18 #define _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;
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_data_size;
55 	uint32_t			 rd_data_offset;
56 };
57 
58 struct hv_channel {
59 	struct hv_softc			*ch_sc;
60 
61 	int				 ch_state;
62 #define  HV_CHANSTATE_OFFERED		  1
63 #define  HV_CHANSTATE_OPENED		  2
64 #define  HV_CHANSTATE_CLOSING		  3
65 #define  HV_CHANSTATE_CLOSED		  4
66 	uint32_t			 ch_id;
67 
68 	struct hv_guid			 ch_type;
69 	struct hv_guid			 ch_inst;
70 	char				 ch_ident[38];
71 
72 	void				*ch_ring;
73 	uint32_t			 ch_ring_gpadl;
74 	uint32_t			 ch_ring_npg;
75 	u_long				 ch_ring_size;
76 
77 	struct hv_ring_data		 ch_wrd;
78 	struct hv_ring_data		 ch_rrd;
79 
80 	uint32_t			 ch_vcpu;
81 
82 	void				(*ch_handler)(void *);
83 	void				 *ch_ctx;
84 	uint8_t				 *ch_buf;
85 	int				  ch_buflen;
86 	struct evcount			  ch_evcnt;
87 
88 	uint32_t			 ch_flags;
89 #define  CHF_BATCHED			  0x0001
90 #define  CHF_MONITOR			  0x0002
91 
92 	uint8_t				 ch_mgroup;
93 	uint8_t				 ch_mindex;
94 	struct hv_mon_param		 ch_monprm __attribute__((aligned(8)));
95 
96 	TAILQ_ENTRY(hv_channel)		 ch_entry;
97 };
98 TAILQ_HEAD(hv_channels, hv_channel);
99 
100 struct hv_attach_args {
101 	void				*aa_parent;
102 	bus_dma_tag_t			 aa_dmat;
103 	struct hv_guid			*aa_type;
104 	struct hv_guid			*aa_inst;
105 	char				*aa_ident;
106 	struct hv_channel		*aa_chan;
107 };
108 
109 struct hv_dev {
110 	struct hv_attach_args		 dv_aa;
111 	SLIST_ENTRY(hv_dev)		 dv_entry;
112 };
113 SLIST_HEAD(hv_devices, hv_dev);
114 
115 struct hv_softc {
116 	struct device			 sc_dev;
117 	struct pvbus_hv			*sc_pvbus;
118 	struct bus_dma_tag		*sc_dmat;
119 
120 	void				*sc_hc;
121 	uint32_t			 sc_features;
122 
123 	uint32_t			 sc_flags;
124 #define  HSF_CONNECTED			  0x0001
125 #define  HSF_OFFERS_DELIVERED		  0x0002
126 
127 	int				 sc_idtvec;
128 	int				 sc_proto;
129 
130 	/* CPU id to VCPU id mapping */
131 	uint32_t			 sc_vcpus[1];	/* XXX: per-cpu */
132 	/* Synthetic Interrupt Message Page (SIMP) */
133 	void				*sc_simp[1];	/* XXX: per-cpu */
134 	/* Synthetic Interrupt Event Flags Page (SIEFP) */
135 	void				*sc_siep[1];	/* XXX: per-cpu */
136 
137 	/* Channel port events page */
138 	void				*sc_events;
139 	u_long				*sc_wevents;	/* Write events */
140 	u_long				*sc_revents;	/* Read events */
141 
142 	/* Monitor pages for parent<->child notifications */
143 	struct vmbus_mnf		*sc_monitor[2];
144 
145 	struct hv_queue	 		 sc_reqs;	/* Request queue */
146 	struct mutex			 sc_reqlck;
147 	struct hv_queue	 		 sc_rsps;	/* Response queue */
148 	struct mutex			 sc_rsplck;
149 
150 	struct hv_offers		 sc_offers;
151 	struct mutex			 sc_offerlck;
152 
153 	struct hv_channels		 sc_channels;
154 	struct mutex			 sc_channelck;
155 
156 	volatile uint32_t		 sc_handle;
157 
158 	struct hv_devices		 sc_devs;
159 	struct mutex			 sc_devlck;
160 
161 	struct task			 sc_sdtask;	/* shutdown */
162 
163 	struct ksensordev		 sc_sensordev;
164 	struct ksensor			 sc_sensor;
165 };
166 
167 static __inline void
168 clear_bit(u_int b, volatile void *p)
169 {
170 	atomic_clearbits_int(((volatile u_int *)p) + (b >> 5), 1 << (b & 0x1f));
171 }
172 
173 static __inline void
174 set_bit(u_int b, volatile void *p)
175 {
176 	atomic_setbits_int(((volatile u_int *)p) + (b >> 5), 1 << (b & 0x1f));
177 }
178 
179 static __inline int
180 test_bit(u_int b, volatile void *p)
181 {
182 	return !!(((volatile u_int *)p)[b >> 5] & (1 << (b & 0x1f)));
183 }
184 
185 int	hv_handle_alloc(struct hv_channel *, void *, uint32_t, uint32_t *);
186 void	hv_handle_free(struct hv_channel *, uint32_t);
187 int	hv_channel_open(struct hv_channel *, void *, size_t, void (*)(void *),
188 	    void *);
189 int	hv_channel_close(struct hv_channel *);
190 int	hv_channel_send(struct hv_channel *, void *, uint32_t, uint64_t,
191 	    int, uint32_t);
192 int	hv_channel_send_sgl(struct hv_channel *, struct vmbus_gpa *,
193 	    uint32_t, void *, uint32_t, uint64_t);
194 int	hv_channel_recv(struct hv_channel *, void *, uint32_t, uint32_t *,
195 	    uint64_t *, int);
196 
197 #endif	/* _HYPERVVAR_H_ */
198