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