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