xen_intr.h (6f3544cd7084abbadd83637993a4f41fd30e6ccd) xen_intr.h (76acc41fb7c740bc49e2638529b8cc750ff281d5)
1/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */
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 */
2#ifndef _XEN_INTR_H_
3#define _XEN_INTR_H_
4
33#ifndef _XEN_INTR_H_
34#define _XEN_INTR_H_
35
5/*
6* The flat IRQ space is divided into two regions:
7* 1. A one-to-one mapping of real physical IRQs. This space is only used
8* if we have physical device-access privilege. This region is at the
9* start of the IRQ space so that existing device drivers do not need
10* to be modified to translate physical IRQ numbers into our IRQ space.
11* 3. A dynamic mapping of inter-domain and Xen-sourced virtual IRQs. These
12* are bound using the provided bind/unbind functions.
13*
14*
15* $FreeBSD$
16*/
36#ifndef __XEN_EVTCHN_PORT_DEFINED__
37typedef uint32_t evtchn_port_t;
38DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
39#define __XEN_EVTCHN_PORT_DEFINED__ 1
40#endif
17
41
18#define PIRQ_BASE 0
19#define NR_PIRQS 128
42/** Registered Xen interrupt callback handle. */
43typedef void * xen_intr_handle_t;
20
44
21#define DYNIRQ_BASE (PIRQ_BASE + NR_PIRQS)
22#define NR_DYNIRQS 128
45/** If non-zero, the hypervisor has been configured to use a direct vector */
46extern int xen_vector_callback_enabled;
23
47
24#define NR_IRQS (NR_PIRQS + NR_DYNIRQS)
48/**
49 * Associate an already allocated local event channel port an interrupt
50 * handler.
51 *
52 * \param dev The device making this bind request.
53 * \param local_port The event channel to bind.
54 * \param filter An interrupt filter handler. Specify NULL
55 * to always dispatch to the ithread handler.
56 * \param handler An interrupt ithread handler. Optional (can
57 * specify NULL) if all necessary event actions
58 * are performed by filter.
59 * \param arg Argument to present to both filter and handler.
60 * \param irqflags Interrupt handler flags. See sys/bus.h.
61 * \param handlep Pointer to an opaque handle used to manage this
62 * registration.
63 *
64 * \returns 0 on success, otherwise an errno.
65 */
66int xen_intr_bind_local_port(device_t dev, evtchn_port_t local_port,
67 driver_filter_t filter, driver_intr_t handler, void *arg,
68 enum intr_type irqflags, xen_intr_handle_t *handlep);
25
69
26#define pirq_to_irq(_x) ((_x) + PIRQ_BASE)
27#define irq_to_pirq(_x) ((_x) - PIRQ_BASE)
70/**
71 * Allocate a local event channel port, accessible by the specified
72 * remote/foreign domain and, if successful, associate the port with
73 * the specified interrupt handler.
74 *
75 * \param dev The device making this bind request.
76 * \param remote_domain Remote domain grant permission to signal the
77 * newly allocated local port.
78 * \param filter An interrupt filter handler. Specify NULL
79 * to always dispatch to the ithread handler.
80 * \param handler An interrupt ithread handler. Optional (can
81 * specify NULL) if all necessary event actions
82 * are performed by filter.
83 * \param arg Argument to present to both filter and handler.
84 * \param irqflags Interrupt handler flags. See sys/bus.h.
85 * \param handlep Pointer to an opaque handle used to manage this
86 * registration.
87 *
88 * \returns 0 on success, otherwise an errno.
89 */
90int xen_intr_alloc_and_bind_local_port(device_t dev,
91 u_int remote_domain, driver_filter_t filter, driver_intr_t handler,
92 void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep);
28
93
29#define dynirq_to_irq(_x) ((_x) + DYNIRQ_BASE)
30#define irq_to_dynirq(_x) ((_x) - DYNIRQ_BASE)
31
32/*
33 * Dynamic binding of event channels and VIRQ sources to guest IRQ space.
94/**
95 * Associate the specified interrupt handler with the remote event
96 * channel port specified by remote_domain and remote_port.
97 *
98 * \param dev The device making this bind request.
99 * \param remote_domain The domain peer for this event channel connection.
100 * \param remote_port Remote domain's local port number for this event
101 * channel port.
102 * \param filter An interrupt filter handler. Specify NULL
103 * to always dispatch to the ithread handler.
104 * \param handler An interrupt ithread handler. Optional (can
105 * specify NULL) if all necessary event actions
106 * are performed by filter.
107 * \param arg Argument to present to both filter and handler.
108 * \param irqflags Interrupt handler flags. See sys/bus.h.
109 * \param handlep Pointer to an opaque handle used to manage this
110 * registration.
111 *
112 * \returns 0 on success, otherwise an errno.
34 */
113 */
114int xen_intr_bind_remote_port(device_t dev, u_int remote_domain,
115 evtchn_port_t remote_port, driver_filter_t filter,
116 driver_intr_t handler, void *arg, enum intr_type irqflags,
117 xen_intr_handle_t *handlep);
35
118
36/*
37 * Bind a caller port event channel to an interrupt handler. If
38 * successful, the guest IRQ number is returned in *irqp. Return zero
39 * on success or errno otherwise.
119/**
120 * Associate the specified interrupt handler with the specified Xen
121 * virtual interrupt source.
122 *
123 * \param dev The device making this bind request.
124 * \param virq The Xen virtual IRQ number for the Xen interrupt
125 * source being hooked.
126 * \param cpu The cpu on which interrupt events should be delivered.
127 * \param filter An interrupt filter handler. Specify NULL
128 * to always dispatch to the ithread handler.
129 * \param handler An interrupt ithread handler. Optional (can
130 * specify NULL) if all necessary event actions
131 * are performed by filter.
132 * \param arg Argument to present to both filter and handler.
133 * \param irqflags Interrupt handler flags. See sys/bus.h.
134 * \param handlep Pointer to an opaque handle used to manage this
135 * registration.
136 *
137 * \returns 0 on success, otherwise an errno.
40 */
138 */
41extern int bind_caller_port_to_irqhandler(unsigned int caller_port,
42 const char *devname, driver_intr_t handler, void *arg,
43 unsigned long irqflags, unsigned int *irqp);
139int xen_intr_bind_virq(device_t dev, u_int virq, u_int cpu,
140 driver_filter_t filter, driver_intr_t handler,
141 void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep);
44
142
45/*
46 * Bind a listening port to an interrupt handler. If successful, the
47 * guest IRQ number is returned in *irqp. Return zero on success or
48 * errno otherwise.
143/**
144 * Associate an interprocessor interrupt vector with an interrupt handler.
145 *
146 * \param dev The device making this bind request.
147 * \param ipi The interprocessor interrupt vector number of the
148 * interrupt source being hooked.
149 * \param cpu The cpu receiving the IPI.
150 * \param filter An interrupt filter handler. Specify NULL
151 * to always dispatch to the ithread handler.
152 * \param irqflags Interrupt handler flags. See sys/bus.h.
153 * \param handlep Pointer to an opaque handle used to manage this
154 * registration.
155 *
156 * \returns 0 on success, otherwise an errno.
49 */
157 */
50extern int bind_listening_port_to_irqhandler(unsigned int remote_domain,
51 const char *devname, driver_intr_t handler, void *arg,
52 unsigned long irqflags, unsigned int *irqp);
158int xen_intr_bind_ipi(device_t dev, u_int ipi, u_int cpu,
159 driver_filter_t filter, enum intr_type irqflags,
160 xen_intr_handle_t *handlep);
53
161
54/*
55 * Bind a VIRQ to an interrupt handler. If successful, the guest IRQ
56 * number is returned in *irqp. Return zero on success or errno
57 * otherwise.
162/**
163 * Unbind an interrupt handler from its interrupt source.
164 *
165 * \param handlep A pointer to the opaque handle that was initialized
166 * at the time the interrupt source was bound.
167 *
168 * \returns 0 on success, otherwise an errno.
169 *
170 * \note The event channel, if any, that was allocated at bind time is
171 * closed upon successful return of this method.
172 *
173 * \note It is always safe to call xen_intr_unbind() on a handle that
174 * has been initilized to NULL.
58 */
175 */
59extern int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
60 const char *devname, driver_filter_t filter, driver_intr_t handler,
61 void *arg, unsigned long irqflags, unsigned int *irqp);
176void xen_intr_unbind(xen_intr_handle_t *handle);
62
177
63/*
64 * Bind an IPI to an interrupt handler. If successful, the guest
65 * IRQ number is returned in *irqp. Return zero on success or errno
66 * otherwise.
178/**
179 * Add a description to an interrupt handler.
180 *
181 * \param handle The opaque handle that was initialized at the time
182 * the interrupt source was bound.
183 *
184 * \param fmt The sprintf compatible format string for the description,
185 * followed by optional sprintf arguments.
186 *
187 * \returns 0 on success, otherwise an errno.
67 */
188 */
68extern int bind_ipi_to_irqhandler(unsigned int ipi, unsigned int cpu,
69 const char *devname, driver_filter_t filter,
70 unsigned long irqflags, unsigned int *irqp);
189int
190xen_intr_describe(xen_intr_handle_t port_handle, const char *fmt, ...)
191 __attribute__((format(printf, 2, 3)));
71
192
72/*
73 * Bind an interdomain event channel to an interrupt handler. If
74 * successful, the guest IRQ number is returned in *irqp. Return zero
75 * on success or errno otherwise.
193/**
194 * Signal the remote peer of an interrupt source associated with an
195 * event channel port.
196 *
197 * \param handle The opaque handle that was initialized at the time
198 * the interrupt source was bound.
199 *
200 * \note For xen interrupt sources other than event channel ports,
201 * this method takes no action.
76 */
202 */
77extern int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
78 unsigned int remote_port, const char *devname,
79 driver_intr_t handler, void *arg,
80 unsigned long irqflags, unsigned int *irqp);
203void xen_intr_signal(xen_intr_handle_t handle);
81
204
82/*
83 * Unbind an interrupt handler using the guest IRQ number returned
84 * when it was bound.
205/**
206 * Get the local event channel port number associated with this interrupt
207 * source.
208 *
209 * \param handle The opaque handle that was initialized at the time
210 * the interrupt source was bound.
211 *
212 * \returns 0 if the handle is invalid, otherwise positive port number.
85 */
213 */
86extern void unbind_from_irqhandler(unsigned int irq);
214evtchn_port_t xen_intr_port(xen_intr_handle_t handle);
87
215
88static __inline__ int irq_cannonicalize(unsigned int irq)
89{
90 return (irq == 2) ? 9 : irq;
91}
92
93extern void disable_irq(unsigned int);
94extern void disable_irq_nosync(unsigned int);
95extern void enable_irq(unsigned int);
96
97extern void irq_suspend(void);
98extern void irq_resume(void);
99
100extern void idle_block(void);
101extern int ap_cpu_initclocks(int cpu);
102
103#endif /* _XEN_INTR_H_ */
216#endif /* _XEN_INTR_H_ */