1 /****************************************************************************** 2 * xen_intr.h 3 * 4 * APIs for managing Xen event channel, virtual IRQ, and physical IRQ 5 * notifications. 6 * 7 * Copyright (c) 2004, K A Fraser 8 * Copyright (c) 2012, Spectra Logic Corporation 9 * 10 * This file may be distributed separately from the Linux kernel, or 11 * incorporated into other software packages, subject to the following license: 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining a copy 14 * of this source file (the "Software"), to deal in the Software without 15 * restriction, including without limitation the rights to use, copy, modify, 16 * merge, publish, distribute, sublicense, and/or sell copies of the Software, 17 * and to permit persons to whom the Software is furnished to do so, subject to 18 * the following conditions: 19 * 20 * The above copyright notice and this permission notice shall be included in 21 * all copies or substantial portions of the Software. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 29 * IN THE SOFTWARE. 30 * 31 * $FreeBSD$ 32 */ 33 #ifndef _XEN_INTR_H_ 34 #define _XEN_INTR_H_ 35 36 #include <xen/interface/event_channel.h> 37 38 /** Registered Xen interrupt callback handle. */ 39 typedef void * xen_intr_handle_t; 40 41 /** If non-zero, the hypervisor has been configured to use a direct vector */ 42 extern int xen_vector_callback_enabled; 43 44 void xen_intr_handle_upcall(struct trapframe *trap_frame); 45 46 /** 47 * Associate an already allocated local event channel port an interrupt 48 * handler. 49 * 50 * \param dev The device making this bind request. 51 * \param local_port The event channel to bind. 52 * \param filter An interrupt filter handler. Specify NULL 53 * to always dispatch to the ithread handler. 54 * \param handler An interrupt ithread handler. Optional (can 55 * specify NULL) if all necessary event actions 56 * are performed by filter. 57 * \param arg Argument to present to both filter and handler. 58 * \param irqflags Interrupt handler flags. See sys/bus.h. 59 * \param handlep Pointer to an opaque handle used to manage this 60 * registration. 61 * 62 * \returns 0 on success, otherwise an errno. 63 */ 64 int xen_intr_bind_local_port(device_t dev, evtchn_port_t local_port, 65 driver_filter_t filter, driver_intr_t handler, void *arg, 66 enum intr_type irqflags, xen_intr_handle_t *handlep); 67 68 /** 69 * Allocate a local event channel port, accessible by the specified 70 * remote/foreign domain and, if successful, associate the port with 71 * the specified interrupt handler. 72 * 73 * \param dev The device making this bind request. 74 * \param remote_domain Remote domain grant permission to signal the 75 * newly allocated local port. 76 * \param filter An interrupt filter handler. Specify NULL 77 * to always dispatch to the ithread handler. 78 * \param handler An interrupt ithread handler. Optional (can 79 * specify NULL) if all necessary event actions 80 * are performed by filter. 81 * \param arg Argument to present to both filter and handler. 82 * \param irqflags Interrupt handler flags. See sys/bus.h. 83 * \param handlep Pointer to an opaque handle used to manage this 84 * registration. 85 * 86 * \returns 0 on success, otherwise an errno. 87 */ 88 int xen_intr_alloc_and_bind_local_port(device_t dev, 89 u_int remote_domain, driver_filter_t filter, driver_intr_t handler, 90 void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep); 91 92 /** 93 * Associate the specified interrupt handler with the remote event 94 * channel port specified by remote_domain and remote_port. 95 * 96 * \param dev The device making this bind request. 97 * \param remote_domain The domain peer for this event channel connection. 98 * \param remote_port Remote domain's local port number for this event 99 * channel port. 100 * \param filter An interrupt filter handler. Specify NULL 101 * to always dispatch to the ithread handler. 102 * \param handler An interrupt ithread handler. Optional (can 103 * specify NULL) if all necessary event actions 104 * are performed by filter. 105 * \param arg Argument to present to both filter and handler. 106 * \param irqflags Interrupt handler flags. See sys/bus.h. 107 * \param handlep Pointer to an opaque handle used to manage this 108 * registration. 109 * 110 * \returns 0 on success, otherwise an errno. 111 */ 112 int xen_intr_bind_remote_port(device_t dev, u_int remote_domain, 113 evtchn_port_t remote_port, driver_filter_t filter, 114 driver_intr_t handler, void *arg, enum intr_type irqflags, 115 xen_intr_handle_t *handlep); 116 117 /** 118 * Associate the specified interrupt handler with the specified Xen 119 * virtual interrupt source. 120 * 121 * \param dev The device making this bind request. 122 * \param virq The Xen virtual IRQ number for the Xen interrupt 123 * source being hooked. 124 * \param cpu The cpu on which interrupt events should be delivered. 125 * \param filter An interrupt filter handler. Specify NULL 126 * to always dispatch to the ithread handler. 127 * \param handler An interrupt ithread handler. Optional (can 128 * specify NULL) if all necessary event actions 129 * are performed by filter. 130 * \param arg Argument to present to both filter and handler. 131 * \param irqflags Interrupt handler flags. See sys/bus.h. 132 * \param handlep Pointer to an opaque handle used to manage this 133 * registration. 134 * 135 * \returns 0 on success, otherwise an errno. 136 */ 137 int xen_intr_bind_virq(device_t dev, u_int virq, u_int cpu, 138 driver_filter_t filter, driver_intr_t handler, 139 void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep); 140 141 /** 142 * Allocate a local event channel port for servicing interprocessor 143 * interupts and, if successful, associate the port with the specified 144 * interrupt handler. 145 * 146 * \param cpu The cpu receiving the IPI. 147 * \param filter The interrupt filter servicing this IPI. 148 * \param irqflags Interrupt handler flags. See sys/bus.h. 149 * \param handlep Pointer to an opaque handle used to manage this 150 * registration. 151 * 152 * \returns 0 on success, otherwise an errno. 153 */ 154 int xen_intr_alloc_and_bind_ipi(u_int cpu, 155 driver_filter_t filter, enum intr_type irqflags, 156 xen_intr_handle_t *handlep); 157 158 /** 159 * Register a physical interrupt vector and setup the interrupt source. 160 * 161 * \param vector The global vector to use. 162 * \param trig Default trigger method. 163 * \param pol Default polarity of the interrupt. 164 * 165 * \returns 0 on success, otherwise an errno. 166 */ 167 int xen_register_pirq(int vector, enum intr_trigger trig, 168 enum intr_polarity pol); 169 170 /** 171 * Unbind an interrupt handler from its interrupt source. 172 * 173 * \param handlep A pointer to the opaque handle that was initialized 174 * at the time the interrupt source was bound. 175 * 176 * \returns 0 on success, otherwise an errno. 177 * 178 * \note The event channel, if any, that was allocated at bind time is 179 * closed upon successful return of this method. 180 * 181 * \note It is always safe to call xen_intr_unbind() on a handle that 182 * has been initilized to NULL. 183 */ 184 void xen_intr_unbind(xen_intr_handle_t *handle); 185 186 /** 187 * Add a description to an interrupt handler. 188 * 189 * \param handle The opaque handle that was initialized at the time 190 * the interrupt source was bound. 191 * 192 * \param fmt The sprintf compatible format string for the description, 193 * followed by optional sprintf arguments. 194 * 195 * \returns 0 on success, otherwise an errno. 196 */ 197 int 198 xen_intr_describe(xen_intr_handle_t port_handle, const char *fmt, ...) 199 __attribute__((format(printf, 2, 3))); 200 201 /** 202 * Signal the remote peer of an interrupt source associated with an 203 * event channel port. 204 * 205 * \param handle The opaque handle that was initialized at the time 206 * the interrupt source was bound. 207 * 208 * \note For xen interrupt sources other than event channel ports, 209 * this method takes no action. 210 */ 211 void xen_intr_signal(xen_intr_handle_t handle); 212 213 /** 214 * Get the local event channel port number associated with this interrupt 215 * source. 216 * 217 * \param handle The opaque handle that was initialized at the time 218 * the interrupt source was bound. 219 * 220 * \returns 0 if the handle is invalid, otherwise positive port number. 221 */ 222 evtchn_port_t xen_intr_port(xen_intr_handle_t handle); 223 224 /** 225 * Setup MSI vector interrupt(s). 226 * 227 * \param dev The device that requests the binding. 228 * 229 * \param vector Requested initial vector to bind the MSI interrupt(s) to. 230 * 231 * \param count Number of vectors to allocate. 232 * 233 * \returns 0 on success, otherwise an errno. 234 */ 235 int xen_register_msi(device_t dev, int vector, int count); 236 237 /** 238 * Teardown a MSI vector interrupt. 239 * 240 * \param vector Requested vector to release. 241 * 242 * \returns 0 on success, otherwise an errno. 243 */ 244 int xen_release_msi(int vector); 245 246 /** 247 * Bind an event channel port with a handler 248 * 249 * \param dev The device making this bind request. 250 * \param filter An interrupt filter handler. Specify NULL 251 * to always dispatch to the ithread handler. 252 * \param handler An interrupt ithread handler. Optional (can 253 * specify NULL) if all necessary event actions 254 * are performed by filter. 255 * \param arg Argument to present to both filter and handler. 256 * \param irqflags Interrupt handler flags. See sys/bus.h. 257 * \param handle Opaque handle used to manage this registration. 258 * 259 * \returns 0 on success, otherwise an errno. 260 */ 261 int xen_intr_add_handler(const char *name, driver_filter_t filter, 262 driver_intr_t handler, void *arg, enum intr_type flags, 263 xen_intr_handle_t handle); 264 265 /** 266 * Get a reference to an event channel port 267 * 268 * \param port Event channel port to which we get a reference. 269 * \param handlep Pointer to an opaque handle used to manage this 270 * registration. 271 * 272 * \returns 0 on success, otherwise an errno. 273 */ 274 int xen_intr_get_evtchn_from_port(evtchn_port_t port, 275 xen_intr_handle_t *handlep); 276 277 #endif /* _XEN_INTR_H_ */ 278