xref: /freebsd/sys/xen/xen_intr.h (revision a0409676120c1e558d0ade943019934e0f15118d)
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 void xen_intr_handle_upcall(struct trapframe *trap_frame);
42 
43 /**
44  * Associate an already allocated local event channel port an interrupt
45  * handler.
46  *
47  * \param dev         The device making this bind request.
48  * \param local_port  The event channel to bind.
49  * \param filter      An interrupt filter handler.  Specify NULL
50  *                    to always dispatch to the ithread handler.
51  * \param handler     An interrupt ithread handler.  Optional (can
52  *                    specify NULL) if all necessary event actions
53  *                    are performed by filter.
54  * \param arg         Argument to present to both filter and handler.
55  * \param irqflags    Interrupt handler flags.  See sys/bus.h.
56  * \param handlep     Pointer to an opaque handle used to manage this
57  *                    registration.
58  *
59  * \returns  0 on success, otherwise an errno.
60  */
61 int xen_intr_bind_local_port(device_t dev, evtchn_port_t local_port,
62 	driver_filter_t filter, driver_intr_t handler, void *arg,
63 	enum intr_type irqflags, xen_intr_handle_t *handlep);
64 
65 /**
66  * Allocate a local event channel port, accessible by the specified
67  * remote/foreign domain and, if successful, associate the port with
68  * the specified interrupt handler.
69  *
70  * \param dev            The device making this bind request.
71  * \param remote_domain  Remote domain grant permission to signal the
72  *                       newly allocated local port.
73  * \param filter         An interrupt filter handler.  Specify NULL
74  *                       to always dispatch to the ithread handler.
75  * \param handler        An interrupt ithread handler.  Optional (can
76  *                       specify NULL) if all necessary event actions
77  *                       are performed by filter.
78  * \param arg            Argument to present to both filter and handler.
79  * \param irqflags       Interrupt handler flags.  See sys/bus.h.
80  * \param handlep        Pointer to an opaque handle used to manage this
81  *                       registration.
82  *
83  * \returns  0 on success, otherwise an errno.
84  */
85 int xen_intr_alloc_and_bind_local_port(device_t dev,
86 	u_int remote_domain, driver_filter_t filter, driver_intr_t handler,
87 	void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep);
88 
89 /**
90  * Associate the specified interrupt handler with the remote event
91  * channel port specified by remote_domain and remote_port.
92  *
93  * \param dev            The device making this bind request.
94  * \param remote_domain  The domain peer for this event channel connection.
95  * \param remote_port    Remote domain's local port number for this event
96  *                       channel port.
97  * \param filter         An interrupt filter handler.  Specify NULL
98  *                       to always dispatch to the ithread handler.
99  * \param handler        An interrupt ithread handler.  Optional (can
100  *                       specify NULL) if all necessary event actions
101  *                       are performed by filter.
102  * \param arg            Argument to present to both filter and handler.
103  * \param irqflags       Interrupt handler flags.  See sys/bus.h.
104  * \param handlep        Pointer to an opaque handle used to manage this
105  *                       registration.
106  *
107  * \returns  0 on success, otherwise an errno.
108  */
109 int xen_intr_bind_remote_port(device_t dev, u_int remote_domain,
110 	evtchn_port_t remote_port, driver_filter_t filter,
111 	driver_intr_t handler, void *arg, enum intr_type irqflags,
112 	xen_intr_handle_t *handlep);
113 
114 /**
115  * Associate the specified interrupt handler with the specified Xen
116  * virtual interrupt source.
117  *
118  * \param dev       The device making this bind request.
119  * \param virq      The Xen virtual IRQ number for the Xen interrupt
120  *                  source being hooked.
121  * \param cpu       The cpu on which interrupt events should be delivered.
122  * \param filter    An interrupt filter handler.  Specify NULL
123  *                  to always dispatch to the ithread handler.
124  * \param handler   An interrupt ithread handler.  Optional (can
125  *                  specify NULL) if all necessary event actions
126  *                  are performed by filter.
127  * \param arg       Argument to present to both filter and handler.
128  * \param irqflags  Interrupt handler flags.  See sys/bus.h.
129  * \param handlep   Pointer to an opaque handle used to manage this
130  *                  registration.
131  *
132  * \returns  0 on success, otherwise an errno.
133  */
134 int xen_intr_bind_virq(device_t dev, u_int virq, u_int cpu,
135 	driver_filter_t filter, driver_intr_t handler,
136 	void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep);
137 
138 /**
139  * Allocate a local event channel port for servicing interprocessor
140  * interupts and, if successful, associate the port with the specified
141  * interrupt handler.
142  *
143  * \param cpu       The cpu receiving the IPI.
144  * \param filter    The interrupt filter servicing this IPI.
145  * \param irqflags  Interrupt handler flags.  See sys/bus.h.
146  * \param handlep   Pointer to an opaque handle used to manage this
147  *                  registration.
148  *
149  * \returns  0 on success, otherwise an errno.
150  */
151 int xen_intr_alloc_and_bind_ipi(u_int cpu,
152 	driver_filter_t filter, enum intr_type irqflags,
153 	xen_intr_handle_t *handlep);
154 
155 /**
156  * Register a physical interrupt vector and setup the interrupt source.
157  *
158  * \param vector        The global vector to use.
159  * \param trig          Default trigger method.
160  * \param pol           Default polarity of the interrupt.
161  *
162  * \returns  0 on success, otherwise an errno.
163  */
164 int xen_register_pirq(int vector, enum intr_trigger trig,
165 	enum intr_polarity pol);
166 
167 /**
168  * Unbind an interrupt handler from its interrupt source.
169  *
170  * \param handlep  A pointer to the opaque handle that was initialized
171  *		   at the time the interrupt source was bound.
172  *
173  * \returns  0 on success, otherwise an errno.
174  *
175  * \note  The event channel, if any, that was allocated at bind time is
176  *        closed upon successful return of this method.
177  *
178  * \note  It is always safe to call xen_intr_unbind() on a handle that
179  *        has been initilized to NULL.
180  */
181 void xen_intr_unbind(xen_intr_handle_t *handle);
182 
183 /**
184  * Add a description to an interrupt handler.
185  *
186  * \param handle  The opaque handle that was initialized at the time
187  *		  the interrupt source was bound.
188  *
189  * \param fmt     The sprintf compatible format string for the description,
190  *                followed by optional sprintf arguments.
191  *
192  * \returns  0 on success, otherwise an errno.
193  */
194 int
195 xen_intr_describe(xen_intr_handle_t port_handle, const char *fmt, ...)
196 	__attribute__((format(printf, 2, 3)));
197 
198 /**
199  * Signal the remote peer of an interrupt source associated with an
200  * event channel port.
201  *
202  * \param handle  The opaque handle that was initialized at the time
203  *                the interrupt source was bound.
204  *
205  * \note  For xen interrupt sources other than event channel ports,
206  *        this method takes no action.
207  */
208 void xen_intr_signal(xen_intr_handle_t handle);
209 
210 /**
211  * Get the local event channel port number associated with this interrupt
212  * source.
213  *
214  * \param handle  The opaque handle that was initialized at the time
215  *                the interrupt source was bound.
216  *
217  * \returns  0 if the handle is invalid, otherwise positive port number.
218  */
219 evtchn_port_t xen_intr_port(xen_intr_handle_t handle);
220 
221 /**
222  * Setup MSI vector interrupt(s).
223  *
224  * \param dev     The device that requests the binding.
225  *
226  * \param vector  Requested initial vector to bind the MSI interrupt(s) to.
227  *
228  * \param count   Number of vectors to allocate.
229  *
230  * \returns  0 on success, otherwise an errno.
231  */
232 int xen_register_msi(device_t dev, int vector, int count);
233 
234 /**
235  * Teardown a MSI vector interrupt.
236  *
237  * \param vector  Requested vector to release.
238  *
239  * \returns  0 on success, otherwise an errno.
240  */
241 int xen_release_msi(int vector);
242 
243 /**
244  * Bind an event channel port with a handler
245  *
246  * \param dev       The device making this bind request.
247  * \param filter    An interrupt filter handler.  Specify NULL
248  *                  to always dispatch to the ithread handler.
249  * \param handler   An interrupt ithread handler.  Optional (can
250  *                  specify NULL) if all necessary event actions
251  *                  are performed by filter.
252  * \param arg       Argument to present to both filter and handler.
253  * \param irqflags  Interrupt handler flags.  See sys/bus.h.
254  * \param handle    Opaque handle used to manage this registration.
255  *
256  * \returns  0 on success, otherwise an errno.
257  */
258 int xen_intr_add_handler(const char *name, driver_filter_t filter,
259 	driver_intr_t handler, void *arg, enum intr_type flags,
260 	xen_intr_handle_t handle);
261 
262 /**
263  * Get a reference to an event channel port
264  *
265  * \param port	    Event channel port to which we get a reference.
266  * \param handlep   Pointer to an opaque handle used to manage this
267  *                  registration.
268  *
269  * \returns  0 on success, otherwise an errno.
270  */
271 int xen_intr_get_evtchn_from_port(evtchn_port_t port,
272 	xen_intr_handle_t *handlep);
273 
274 /**
275  * Register the IO-APIC PIRQs when running in legacy PVH Dom0 mode.
276  *
277  * \param pic	    PIC instance.
278  *
279  * NB: this should be removed together with the support for legacy PVH mode.
280  */
281 struct pic;
282 void xenpv_register_pirqs(struct pic *pic);
283 
284 #endif /* _XEN_INTR_H_ */
285