xref: /openbsd-src/sys/dev/pv/hypervvar.h (revision 0b7734b3d77bb9b21afec6f4621cae6c805dbd45)
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 hv_input_post_message	 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 hv_channel_offer_channel	 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 hv_ring_buffer		*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_relid;
67 
68 	struct hv_guid			 ch_type;
69 	struct hv_guid			 ch_inst;
70 	char				 ch_ident[38];
71 
72 	uint8_t				 ch_mgroup;
73 	uint8_t				 ch_mindex;
74 
75 	void				*ch_ring;
76 	uint32_t			 ch_ring_hndl;
77 	uint32_t			 ch_ring_npg;
78 	ulong				 ch_ring_size;
79 
80 	struct hv_ring_data		 ch_wrd;
81 	struct hv_ring_data		 ch_rrd;
82 
83 	uint32_t			 ch_vcpu;
84 
85 	void				(*ch_handler)(void *);
86 	void				 *ch_ctx;
87 	uint8_t				 *ch_buf;
88 	int				  ch_buflen;
89 	struct evcount			  ch_evcnt;
90 
91 	uint32_t			 ch_flags;
92 #define  CHF_BATCHED			  0x0001
93 #define  CHF_DEDICATED			  0x0002
94 #define  CHF_MONITOR			  0x0004
95 
96 	struct hv_input_signal_event	 ch_sigevt __attribute__((aligned(8)));
97 
98 	TAILQ_ENTRY(hv_channel)		 ch_entry;
99 };
100 TAILQ_HEAD(hv_channels, hv_channel);
101 
102 struct hv_attach_args {
103 	void				*aa_parent;
104 	bus_dma_tag_t			 aa_dmat;
105 	struct hv_guid			*aa_type;
106 	struct hv_guid			*aa_inst;
107 	char				*aa_ident;
108 	struct hv_channel		*aa_chan;
109 };
110 
111 struct hv_dev {
112 	struct hv_attach_args		 dv_aa;
113 	SLIST_ENTRY(hv_dev)		 dv_entry;
114 };
115 SLIST_HEAD(hv_devices, hv_dev);
116 
117 struct hv_softc {
118 	struct device			 sc_dev;
119 	struct pvbus_hv			*sc_pvbus;
120 	struct bus_dma_tag		*sc_dmat;
121 
122 	void				*sc_hc;
123 	uint32_t			 sc_features;
124 
125 	uint32_t			 sc_flags;
126 #define  HSF_CONNECTED			  0x0001
127 #define  HSF_OFFERS_DELIVERED		  0x0002
128 
129 	int				 sc_idtvec;
130 	int				 sc_proto;
131 
132 	/* CPU id to VCPU id mapping */
133 	uint32_t			 sc_vcpus[1];	/* XXX: per-cpu */
134 	/* Synthetic Interrupt Message Page (SIMP) */
135 	void				*sc_simp[1];	/* XXX: per-cpu */
136 	/* Synthetic Interrupt Event Flags Page (SIEFP) */
137 	void				*sc_siep[1];	/* XXX: per-cpu */
138 
139 	/* Channel port events page */
140 	void				*sc_events;
141 	uint32_t			*sc_wevents;	/* Write events */
142 	uint32_t			*sc_revents;	/* Read events */
143 
144 	/* Monitor pages for parent<->child notifications */
145 	struct hv_monitor_page		*sc_monitor[2];
146 
147 	struct hv_queue	 		 sc_reqs;	/* Request queue */
148 	struct mutex			 sc_reqlck;
149 	struct hv_queue	 		 sc_rsps;	/* Response queue */
150 	struct mutex			 sc_rsplck;
151 
152 	struct hv_offers		 sc_offers;
153 	struct mutex			 sc_offerlck;
154 
155 	struct hv_channels		 sc_channels;
156 	struct mutex			 sc_channelck;
157 
158 	volatile uint32_t		 sc_handle;
159 
160 	struct hv_devices		 sc_devs;
161 	struct mutex			 sc_devlck;
162 
163 	struct task			 sc_sdtask;	/* shutdown */
164 
165 	struct ksensordev		 sc_sensordev;
166 	struct ksensor			 sc_sensor;
167 };
168 
169 static inline int
170 atomic_setbit_ptr(volatile void *ptr, int bit)
171 {
172 	int obit;
173 
174 	__asm__ __volatile__ ("lock btsl %2,%1; sbbl %0,%0" :
175 	    "=r" (obit), "=m" (*(volatile long *)ptr) : "Ir" (bit) :
176 	    "memory");
177 
178 	return (obit);
179 }
180 
181 static inline int
182 atomic_clearbit_ptr(volatile void *ptr, int bit)
183 {
184 	int obit;
185 
186 	__asm__ __volatile__ ("lock btrl %2,%1; sbbl %0,%0" :
187 	    "=r" (obit), "=m" (*(volatile long *)ptr) : "Ir" (bit) :
188 	    "memory");
189 
190 	return (obit);
191 }
192 
193 int	hv_handle_alloc(struct hv_channel *, void *, uint32_t, uint32_t *);
194 void	hv_handle_free(struct hv_channel *, uint32_t);
195 int	hv_channel_open(struct hv_channel *, void *, size_t, void (*)(void *),
196 	    void *);
197 int	hv_channel_close(struct hv_channel *);
198 int	hv_channel_send(struct hv_channel *, void *, uint32_t, uint64_t,
199 	    int, uint32_t);
200 int	hv_channel_sendbuf(struct hv_channel *, struct hv_page_buffer *,
201 	    uint32_t, void *, uint32_t, uint64_t);
202 int	hv_channel_recv(struct hv_channel *, void *, uint32_t, uint32_t *,
203 	    uint64_t *, int);
204 
205 #endif	/* _HYPERVVAR_H_ */
206