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