xref: /freebsd/sys/xen/xen_intr.h (revision a5921bc3653e2e286715e6fe8d473ec0d02da38c)
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 dev       The device making this bind request.
147  * \param cpu       The cpu receiving the IPI.
148  * \param filter    The interrupt filter servicing this IPI.
149  * \param irqflags  Interrupt handler flags.  See sys/bus.h.
150  * \param handlep   Pointer to an opaque handle used to manage this
151  *                  registration.
152  *
153  * \returns  0 on success, otherwise an errno.
154  */
155 int xen_intr_alloc_and_bind_ipi(device_t dev, u_int cpu,
156 	driver_filter_t filter, enum intr_type irqflags,
157 	xen_intr_handle_t *handlep);
158 
159 /**
160  * Register a physical interrupt vector and setup the interrupt source.
161  *
162  * \param vector        The global vector to use.
163  * \param trig          Default trigger method.
164  * \param pol           Default polarity of the interrupt.
165  *
166  * \returns  0 on success, otherwise an errno.
167  */
168 int xen_register_pirq(int vector, enum intr_trigger trig,
169 	enum intr_polarity pol);
170 
171 /**
172  * Unbind an interrupt handler from its interrupt source.
173  *
174  * \param handlep  A pointer to the opaque handle that was initialized
175  *		   at the time the interrupt source was bound.
176  *
177  * \returns  0 on success, otherwise an errno.
178  *
179  * \note  The event channel, if any, that was allocated at bind time is
180  *        closed upon successful return of this method.
181  *
182  * \note  It is always safe to call xen_intr_unbind() on a handle that
183  *        has been initilized to NULL.
184  */
185 void xen_intr_unbind(xen_intr_handle_t *handle);
186 
187 /**
188  * Add a description to an interrupt handler.
189  *
190  * \param handle  The opaque handle that was initialized at the time
191  *		  the interrupt source was bound.
192  *
193  * \param fmt     The sprintf compatible format string for the description,
194  *                followed by optional sprintf arguments.
195  *
196  * \returns  0 on success, otherwise an errno.
197  */
198 int
199 xen_intr_describe(xen_intr_handle_t port_handle, const char *fmt, ...)
200 	__attribute__((format(printf, 2, 3)));
201 
202 /**
203  * Signal the remote peer of an interrupt source associated with an
204  * event channel port.
205  *
206  * \param handle  The opaque handle that was initialized at the time
207  *                the interrupt source was bound.
208  *
209  * \note  For xen interrupt sources other than event channel ports,
210  *        this method takes no action.
211  */
212 void xen_intr_signal(xen_intr_handle_t handle);
213 
214 /**
215  * Get the local event channel port number associated with this interrupt
216  * source.
217  *
218  * \param handle  The opaque handle that was initialized at the time
219  *                the interrupt source was bound.
220  *
221  * \returns  0 if the handle is invalid, otherwise positive port number.
222  */
223 evtchn_port_t xen_intr_port(xen_intr_handle_t handle);
224 
225 /**
226  * Setup MSI vector interrupt(s).
227  *
228  * \param dev     The device that requests the binding.
229  *
230  * \param vector  Requested initial vector to bind the MSI interrupt(s) to.
231  *
232  * \param count   Number of vectors to allocate.
233  *
234  * \returns  0 on success, otherwise an errno.
235  */
236 int xen_register_msi(device_t dev, int vector, int count);
237 
238 /**
239  * Teardown a MSI vector interrupt.
240  *
241  * \param vector  Requested vector to release.
242  *
243  * \returns  0 on success, otherwise an errno.
244  */
245 int xen_release_msi(int vector);
246 
247 /**
248  * Bind an event channel port with a handler
249  *
250  * \param dev       The device making this bind request.
251  * \param filter    An interrupt filter handler.  Specify NULL
252  *                  to always dispatch to the ithread handler.
253  * \param handler   An interrupt ithread handler.  Optional (can
254  *                  specify NULL) if all necessary event actions
255  *                  are performed by filter.
256  * \param arg       Argument to present to both filter and handler.
257  * \param irqflags  Interrupt handler flags.  See sys/bus.h.
258  * \param handle    Opaque handle used to manage this registration.
259  *
260  * \returns  0 on success, otherwise an errno.
261  */
262 int xen_intr_add_handler(device_t dev, driver_filter_t filter,
263 	driver_intr_t handler, void *arg, enum intr_type flags,
264 	xen_intr_handle_t handle);
265 
266 #endif /* _XEN_INTR_H_ */
267