1/*
2 * Permission is hereby granted, free of charge, to any person obtaining a copy
3 * of this software and associated documentation files (the "Software"), to
4 * deal in the Software without restriction, including without limitation the
5 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6 * sell copies of the Software, and to permit persons to whom the Software is
7 * furnished to do so, subject to the following conditions:
8 *
9 * The above copyright notice and this permission notice shall be included in
10 * all copies or substantial portions of the Software.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18 * DEALINGS IN THE SOFTWARE.
19 */
20
21#ifndef __XEN_PUBLIC_PHYSDEV_H__
22#define __XEN_PUBLIC_PHYSDEV_H__
23
24#include "xen.h"
25
26/*
27 * Prototype for this hypercall is:
28 *  int physdev_op(int cmd, void *args)
29 * @cmd  == PHYSDEVOP_??? (physdev operation).
30 * @args == Operation-specific extra arguments (NULL if none).
31 */
32
33/*
34 * Notify end-of-interrupt (EOI) for the specified IRQ.
35 * @arg == pointer to physdev_eoi structure.
36 */
37#define PHYSDEVOP_eoi                   12
38struct physdev_eoi {
39    /* IN */
40    uint32_t irq;
41};
42typedef struct physdev_eoi physdev_eoi_t;
43DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
44
45/*
46 * Register a shared page for the hypervisor to indicate whether the guest
47 * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly
48 * once the guest used this function in that the associated event channel
49 * will automatically get unmasked. The page registered is used as a bit
50 * array indexed by Xen's PIRQ value.
51 */
52#define PHYSDEVOP_pirq_eoi_gmfn_v1       17
53/*
54 * Register a shared page for the hypervisor to indicate whether the
55 * guest must issue PHYSDEVOP_eoi. This hypercall is very similar to
56 * PHYSDEVOP_pirq_eoi_gmfn_v1 but it doesn't change the semantics of
57 * PHYSDEVOP_eoi. The page registered is used as a bit array indexed by
58 * Xen's PIRQ value.
59 */
60#define PHYSDEVOP_pirq_eoi_gmfn_v2       28
61struct physdev_pirq_eoi_gmfn {
62    /* IN */
63    xen_pfn_t gmfn;
64};
65typedef struct physdev_pirq_eoi_gmfn physdev_pirq_eoi_gmfn_t;
66DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_gmfn_t);
67
68/*
69 * Query the status of an IRQ line.
70 * @arg == pointer to physdev_irq_status_query structure.
71 */
72#define PHYSDEVOP_irq_status_query       5
73struct physdev_irq_status_query {
74    /* IN */
75    uint32_t irq;
76    /* OUT */
77    uint32_t flags; /* XENIRQSTAT_* */
78};
79typedef struct physdev_irq_status_query physdev_irq_status_query_t;
80DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t);
81
82/* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */
83#define _XENIRQSTAT_needs_eoi   (0)
84#define  XENIRQSTAT_needs_eoi   (1U<<_XENIRQSTAT_needs_eoi)
85
86/* IRQ shared by multiple guests? */
87#define _XENIRQSTAT_shared      (1)
88#define  XENIRQSTAT_shared      (1U<<_XENIRQSTAT_shared)
89
90/*
91 * Set the current VCPU's I/O privilege level.
92 * @arg == pointer to physdev_set_iopl structure.
93 */
94#define PHYSDEVOP_set_iopl               6
95struct physdev_set_iopl {
96    /* IN */
97    uint32_t iopl;
98};
99typedef struct physdev_set_iopl physdev_set_iopl_t;
100DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t);
101
102/*
103 * Set the current VCPU's I/O-port permissions bitmap.
104 * @arg == pointer to physdev_set_iobitmap structure.
105 */
106#define PHYSDEVOP_set_iobitmap           7
107struct physdev_set_iobitmap {
108    /* IN */
109#if __XEN_INTERFACE_VERSION__ >= 0x00030205
110    XEN_GUEST_HANDLE(uint8) bitmap;
111#else
112    uint8_t *bitmap;
113#endif
114    uint32_t nr_ports;
115};
116typedef struct physdev_set_iobitmap physdev_set_iobitmap_t;
117DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t);
118
119/*
120 * Read or write an IO-APIC register.
121 * @arg == pointer to physdev_apic structure.
122 */
123#define PHYSDEVOP_apic_read              8
124#define PHYSDEVOP_apic_write             9
125struct physdev_apic {
126    /* IN */
127    unsigned long apic_physbase;
128    uint32_t reg;
129    /* IN or OUT */
130    uint32_t value;
131};
132typedef struct physdev_apic physdev_apic_t;
133DEFINE_XEN_GUEST_HANDLE(physdev_apic_t);
134
135/*
136 * Allocate or free a physical upcall vector for the specified IRQ line.
137 * @arg == pointer to physdev_irq structure.
138 */
139#define PHYSDEVOP_alloc_irq_vector      10
140#define PHYSDEVOP_free_irq_vector       11
141struct physdev_irq {
142    /* IN */
143    uint32_t irq;
144    /* IN or OUT */
145    uint32_t vector;
146};
147typedef struct physdev_irq physdev_irq_t;
148DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
149
150#define MAP_PIRQ_TYPE_MSI               0x0
151#define MAP_PIRQ_TYPE_GSI               0x1
152#define MAP_PIRQ_TYPE_UNKNOWN           0x2
153#define MAP_PIRQ_TYPE_MSI_SEG           0x3
154
155#define PHYSDEVOP_map_pirq               13
156struct physdev_map_pirq {
157    domid_t domid;
158    /* IN */
159    int type;
160    /* IN */
161    int index;
162    /* IN or OUT */
163    int pirq;
164    /* IN - high 16 bits hold segment for MAP_PIRQ_TYPE_MSI_SEG */
165    int bus;
166    /* IN */
167    int devfn;
168    /* IN */
169    int entry_nr;
170    /* IN */
171    uint64_t table_base;
172};
173typedef struct physdev_map_pirq physdev_map_pirq_t;
174DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t);
175
176#define PHYSDEVOP_unmap_pirq             14
177struct physdev_unmap_pirq {
178    domid_t domid;
179    /* IN */
180    int pirq;
181};
182
183typedef struct physdev_unmap_pirq physdev_unmap_pirq_t;
184DEFINE_XEN_GUEST_HANDLE(physdev_unmap_pirq_t);
185
186#define PHYSDEVOP_manage_pci_add         15
187#define PHYSDEVOP_manage_pci_remove      16
188struct physdev_manage_pci {
189    /* IN */
190    uint8_t bus;
191    uint8_t devfn;
192};
193
194typedef struct physdev_manage_pci physdev_manage_pci_t;
195DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t);
196
197#define PHYSDEVOP_restore_msi            19
198struct physdev_restore_msi {
199    /* IN */
200    uint8_t bus;
201    uint8_t devfn;
202};
203typedef struct physdev_restore_msi physdev_restore_msi_t;
204DEFINE_XEN_GUEST_HANDLE(physdev_restore_msi_t);
205
206#define PHYSDEVOP_manage_pci_add_ext     20
207struct physdev_manage_pci_ext {
208    /* IN */
209    uint8_t bus;
210    uint8_t devfn;
211    unsigned is_extfn;
212    unsigned is_virtfn;
213    struct {
214        uint8_t bus;
215        uint8_t devfn;
216    } physfn;
217};
218
219typedef struct physdev_manage_pci_ext physdev_manage_pci_ext_t;
220DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_ext_t);
221
222/*
223 * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
224 * hypercall since 0x00030202.
225 */
226struct physdev_op {
227    uint32_t cmd;
228    union {
229        struct physdev_irq_status_query      irq_status_query;
230        struct physdev_set_iopl              set_iopl;
231        struct physdev_set_iobitmap          set_iobitmap;
232        struct physdev_apic                  apic_op;
233        struct physdev_irq                   irq_op;
234    } u;
235};
236typedef struct physdev_op physdev_op_t;
237DEFINE_XEN_GUEST_HANDLE(physdev_op_t);
238
239#define PHYSDEVOP_setup_gsi    21
240struct physdev_setup_gsi {
241    int gsi;
242    /* IN */
243    uint8_t triggering;
244    /* IN */
245    uint8_t polarity;
246    /* IN */
247};
248
249typedef struct physdev_setup_gsi physdev_setup_gsi_t;
250DEFINE_XEN_GUEST_HANDLE(physdev_setup_gsi_t);
251
252/* leave PHYSDEVOP 22 free */
253
254/* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI
255 * the hypercall returns a free pirq */
256#define PHYSDEVOP_get_free_pirq    23
257struct physdev_get_free_pirq {
258    /* IN */
259    int type;
260    /* OUT */
261    uint32_t pirq;
262};
263
264typedef struct physdev_get_free_pirq physdev_get_free_pirq_t;
265DEFINE_XEN_GUEST_HANDLE(physdev_get_free_pirq_t);
266
267#define XEN_PCI_MMCFG_RESERVED         0x1
268
269#define PHYSDEVOP_pci_mmcfg_reserved    24
270struct physdev_pci_mmcfg_reserved {
271    uint64_t address;
272    uint16_t segment;
273    uint8_t start_bus;
274    uint8_t end_bus;
275    uint32_t flags;
276};
277typedef struct physdev_pci_mmcfg_reserved physdev_pci_mmcfg_reserved_t;
278DEFINE_XEN_GUEST_HANDLE(physdev_pci_mmcfg_reserved_t);
279
280#define XEN_PCI_DEV_EXTFN              0x1
281#define XEN_PCI_DEV_VIRTFN             0x2
282#define XEN_PCI_DEV_PXM                0x4
283
284#define PHYSDEVOP_pci_device_add        25
285struct physdev_pci_device_add {
286    /* IN */
287    uint16_t seg;
288    uint8_t bus;
289    uint8_t devfn;
290    uint32_t flags;
291    struct {
292        uint8_t bus;
293        uint8_t devfn;
294    } physfn;
295#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
296    uint32_t optarr[];
297#elif defined(__GNUC__)
298    uint32_t optarr[0];
299#endif
300};
301typedef struct physdev_pci_device_add physdev_pci_device_add_t;
302DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_add_t);
303
304#define PHYSDEVOP_pci_device_remove     26
305#define PHYSDEVOP_restore_msi_ext       27
306struct physdev_pci_device {
307    /* IN */
308    uint16_t seg;
309    uint8_t bus;
310    uint8_t devfn;
311};
312typedef struct physdev_pci_device physdev_pci_device_t;
313DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_t);
314
315/*
316 * Notify that some PIRQ-bound event channels have been unmasked.
317 * ** This command is obsolete since interface version 0x00030202 and is **
318 * ** unsupported by newer versions of Xen.                              **
319 */
320#define PHYSDEVOP_IRQ_UNMASK_NOTIFY      4
321
322/*
323 * These all-capitals physdev operation names are superceded by the new names
324 * (defined above) since interface version 0x00030202.
325 */
326#define PHYSDEVOP_IRQ_STATUS_QUERY       PHYSDEVOP_irq_status_query
327#define PHYSDEVOP_SET_IOPL               PHYSDEVOP_set_iopl
328#define PHYSDEVOP_SET_IOBITMAP           PHYSDEVOP_set_iobitmap
329#define PHYSDEVOP_APIC_READ              PHYSDEVOP_apic_read
330#define PHYSDEVOP_APIC_WRITE             PHYSDEVOP_apic_write
331#define PHYSDEVOP_ASSIGN_VECTOR          PHYSDEVOP_alloc_irq_vector
332#define PHYSDEVOP_FREE_VECTOR            PHYSDEVOP_free_irq_vector
333#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi
334#define PHYSDEVOP_IRQ_SHARED             XENIRQSTAT_shared
335
336#if __XEN_INTERFACE_VERSION__ < 0x00040200
337#define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v1
338#else
339#define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v2
340#endif
341
342#endif /* __XEN_PUBLIC_PHYSDEV_H__ */
343
344/*
345 * Local variables:
346 * mode: C
347 * c-set-style: "BSD"
348 * c-basic-offset: 4
349 * tab-width: 4
350 * indent-tabs-mode: nil
351 * End:
352 */
353