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  * Copyright (c) 2006, Keir Fraser
21  */
22 
23 #ifndef __XEN_PUBLIC_PHYSDEV_H__
24 #define __XEN_PUBLIC_PHYSDEV_H__
25 
26 #include "xen.h"
27 
28 /*
29  * Prototype for this hypercall is:
30  *  int physdev_op(int cmd, void *args)
31  * @cmd  == PHYSDEVOP_??? (physdev operation).
32  * @args == Operation-specific extra arguments (NULL if none).
33  */
34 
35 /*
36  * Notify end-of-interrupt (EOI) for the specified IRQ.
37  * @arg == pointer to physdev_eoi structure.
38  */
39 #define PHYSDEVOP_eoi                   12
40 struct physdev_eoi {
41     /* IN */
42     uint32_t irq;
43 };
44 typedef struct physdev_eoi physdev_eoi_t;
45 DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
46 
47 /*
48  * Register a shared page for the hypervisor to indicate whether the guest
49  * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly
50  * once the guest used this function in that the associated event channel
51  * will automatically get unmasked. The page registered is used as a bit
52  * array indexed by Xen's PIRQ value.
53  */
54 #define PHYSDEVOP_pirq_eoi_gmfn_v1       17
55 /*
56  * Register a shared page for the hypervisor to indicate whether the
57  * guest must issue PHYSDEVOP_eoi. This hypercall is very similar to
58  * PHYSDEVOP_pirq_eoi_gmfn_v1 but it doesn't change the semantics of
59  * PHYSDEVOP_eoi. The page registered is used as a bit array indexed by
60  * Xen's PIRQ value.
61  */
62 #define PHYSDEVOP_pirq_eoi_gmfn_v2       28
63 struct physdev_pirq_eoi_gmfn {
64     /* IN */
65     xen_pfn_t gmfn;
66 };
67 typedef struct physdev_pirq_eoi_gmfn physdev_pirq_eoi_gmfn_t;
68 DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_gmfn_t);
69 
70 /*
71  * Query the status of an IRQ line.
72  * @arg == pointer to physdev_irq_status_query structure.
73  */
74 #define PHYSDEVOP_irq_status_query       5
75 struct physdev_irq_status_query {
76     /* IN */
77     uint32_t irq;
78     /* OUT */
79     uint32_t flags; /* XENIRQSTAT_* */
80 };
81 typedef struct physdev_irq_status_query physdev_irq_status_query_t;
82 DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t);
83 
84 /* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */
85 #define _XENIRQSTAT_needs_eoi   (0)
86 #define  XENIRQSTAT_needs_eoi   (1U<<_XENIRQSTAT_needs_eoi)
87 
88 /* IRQ shared by multiple guests? */
89 #define _XENIRQSTAT_shared      (1)
90 #define  XENIRQSTAT_shared      (1U<<_XENIRQSTAT_shared)
91 
92 /*
93  * Set the current VCPU's I/O privilege level.
94  * @arg == pointer to physdev_set_iopl structure.
95  */
96 #define PHYSDEVOP_set_iopl               6
97 struct physdev_set_iopl {
98     /* IN */
99     uint32_t iopl;
100 };
101 typedef struct physdev_set_iopl physdev_set_iopl_t;
102 DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t);
103 
104 /*
105  * Set the current VCPU's I/O-port permissions bitmap.
106  * @arg == pointer to physdev_set_iobitmap structure.
107  */
108 #define PHYSDEVOP_set_iobitmap           7
109 struct physdev_set_iobitmap {
110     /* IN */
111 #if __XEN_INTERFACE_VERSION__ >= 0x00030205
112     XEN_GUEST_HANDLE(uint8) bitmap;
113 #else
114     uint8_t *bitmap;
115 #endif
116     uint32_t nr_ports;
117 };
118 typedef struct physdev_set_iobitmap physdev_set_iobitmap_t;
119 DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t);
120 
121 /*
122  * Read or write an IO-APIC register.
123  * @arg == pointer to physdev_apic structure.
124  */
125 #define PHYSDEVOP_apic_read              8
126 #define PHYSDEVOP_apic_write             9
127 struct physdev_apic {
128     /* IN */
129     unsigned long apic_physbase;
130     uint32_t reg;
131     /* IN or OUT */
132     uint32_t value;
133 };
134 typedef struct physdev_apic physdev_apic_t;
135 DEFINE_XEN_GUEST_HANDLE(physdev_apic_t);
136 
137 /*
138  * Allocate or free a physical upcall vector for the specified IRQ line.
139  * @arg == pointer to physdev_irq structure.
140  */
141 #define PHYSDEVOP_alloc_irq_vector      10
142 #define PHYSDEVOP_free_irq_vector       11
143 struct physdev_irq {
144     /* IN */
145     uint32_t irq;
146     /* IN or OUT */
147     uint32_t vector;
148 };
149 typedef struct physdev_irq physdev_irq_t;
150 DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
151 
152 #define MAP_PIRQ_TYPE_MSI               0x0
153 #define MAP_PIRQ_TYPE_GSI               0x1
154 #define MAP_PIRQ_TYPE_UNKNOWN           0x2
155 #define MAP_PIRQ_TYPE_MSI_SEG           0x3
156 #define MAP_PIRQ_TYPE_MULTI_MSI         0x4
157 
158 #define PHYSDEVOP_map_pirq               13
159 struct physdev_map_pirq {
160     domid_t domid;
161     /* IN */
162     int type;
163     /* IN (ignored for ..._MULTI_MSI) */
164     int index;
165     /* IN or OUT */
166     int pirq;
167     /* IN - high 16 bits hold segment for ..._MSI_SEG and ..._MULTI_MSI */
168     int bus;
169     /* IN */
170     int devfn;
171     /* IN (also OUT for ..._MULTI_MSI) */
172     int entry_nr;
173     /* IN */
174     uint64_t table_base;
175 };
176 typedef struct physdev_map_pirq physdev_map_pirq_t;
177 DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t);
178 
179 #define PHYSDEVOP_unmap_pirq             14
180 struct physdev_unmap_pirq {
181     domid_t domid;
182     /* IN */
183     int pirq;
184 };
185 
186 typedef struct physdev_unmap_pirq physdev_unmap_pirq_t;
187 DEFINE_XEN_GUEST_HANDLE(physdev_unmap_pirq_t);
188 
189 #define PHYSDEVOP_manage_pci_add         15
190 #define PHYSDEVOP_manage_pci_remove      16
191 struct physdev_manage_pci {
192     /* IN */
193     uint8_t bus;
194     uint8_t devfn;
195 };
196 
197 typedef struct physdev_manage_pci physdev_manage_pci_t;
198 DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t);
199 
200 #define PHYSDEVOP_restore_msi            19
201 struct physdev_restore_msi {
202     /* IN */
203     uint8_t bus;
204     uint8_t devfn;
205 };
206 typedef struct physdev_restore_msi physdev_restore_msi_t;
207 DEFINE_XEN_GUEST_HANDLE(physdev_restore_msi_t);
208 
209 #define PHYSDEVOP_manage_pci_add_ext     20
210 struct physdev_manage_pci_ext {
211     /* IN */
212     uint8_t bus;
213     uint8_t devfn;
214     unsigned is_extfn;
215     unsigned is_virtfn;
216     struct {
217         uint8_t bus;
218         uint8_t devfn;
219     } physfn;
220 };
221 
222 typedef struct physdev_manage_pci_ext physdev_manage_pci_ext_t;
223 DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_ext_t);
224 
225 /*
226  * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
227  * hypercall since 0x00030202.
228  */
229 struct physdev_op {
230     uint32_t cmd;
231     union {
232         struct physdev_irq_status_query      irq_status_query;
233         struct physdev_set_iopl              set_iopl;
234         struct physdev_set_iobitmap          set_iobitmap;
235         struct physdev_apic                  apic_op;
236         struct physdev_irq                   irq_op;
237     } u;
238 };
239 typedef struct physdev_op physdev_op_t;
240 DEFINE_XEN_GUEST_HANDLE(physdev_op_t);
241 
242 #define PHYSDEVOP_setup_gsi    21
243 struct physdev_setup_gsi {
244     int gsi;
245     /* IN */
246     uint8_t triggering;
247     /* IN */
248     uint8_t polarity;
249     /* IN */
250 };
251 
252 typedef struct physdev_setup_gsi physdev_setup_gsi_t;
253 DEFINE_XEN_GUEST_HANDLE(physdev_setup_gsi_t);
254 
255 /* leave PHYSDEVOP 22 free */
256 
257 /* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI
258  * the hypercall returns a free pirq */
259 #define PHYSDEVOP_get_free_pirq    23
260 struct physdev_get_free_pirq {
261     /* IN */
262     int type;
263     /* OUT */
264     uint32_t pirq;
265 };
266 
267 typedef struct physdev_get_free_pirq physdev_get_free_pirq_t;
268 DEFINE_XEN_GUEST_HANDLE(physdev_get_free_pirq_t);
269 
270 #define XEN_PCI_MMCFG_RESERVED         0x1
271 
272 #define PHYSDEVOP_pci_mmcfg_reserved    24
273 struct physdev_pci_mmcfg_reserved {
274     uint64_t address;
275     uint16_t segment;
276     uint8_t start_bus;
277     uint8_t end_bus;
278     uint32_t flags;
279 };
280 typedef struct physdev_pci_mmcfg_reserved physdev_pci_mmcfg_reserved_t;
281 DEFINE_XEN_GUEST_HANDLE(physdev_pci_mmcfg_reserved_t);
282 
283 #define XEN_PCI_DEV_EXTFN              0x1
284 #define XEN_PCI_DEV_VIRTFN             0x2
285 #define XEN_PCI_DEV_PXM                0x4
286 
287 #define PHYSDEVOP_pci_device_add        25
288 struct physdev_pci_device_add {
289     /* IN */
290     uint16_t seg;
291     uint8_t bus;
292     uint8_t devfn;
293     uint32_t flags;
294     struct {
295         uint8_t bus;
296         uint8_t devfn;
297     } physfn;
298     /*
299      * Optional parameters array.
300      * First element ([0]) is PXM domain associated with the device (if
301      * XEN_PCI_DEV_PXM is set)
302      */
303 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
304     uint32_t optarr[];
305 #elif defined(__GNUC__)
306     uint32_t optarr[0];
307 #endif
308 };
309 typedef struct physdev_pci_device_add physdev_pci_device_add_t;
310 DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_add_t);
311 
312 #define PHYSDEVOP_pci_device_remove     26
313 #define PHYSDEVOP_restore_msi_ext       27
314 /*
315  * Dom0 should use these two to announce MMIO resources assigned to
316  * MSI-X capable devices won't (prepare) or may (release) change.
317  */
318 #define PHYSDEVOP_prepare_msix          30
319 #define PHYSDEVOP_release_msix          31
320 struct physdev_pci_device {
321     /* IN */
322     uint16_t seg;
323     uint8_t bus;
324     uint8_t devfn;
325 };
326 typedef struct physdev_pci_device physdev_pci_device_t;
327 DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_t);
328 
329 #define PHYSDEVOP_DBGP_RESET_PREPARE    1
330 #define PHYSDEVOP_DBGP_RESET_DONE       2
331 
332 #define PHYSDEVOP_DBGP_BUS_UNKNOWN      0
333 #define PHYSDEVOP_DBGP_BUS_PCI          1
334 
335 #define PHYSDEVOP_dbgp_op               29
336 struct physdev_dbgp_op {
337     /* IN */
338     uint8_t op;
339     uint8_t bus;
340     union {
341         struct physdev_pci_device pci;
342     } u;
343 };
344 typedef struct physdev_dbgp_op physdev_dbgp_op_t;
345 DEFINE_XEN_GUEST_HANDLE(physdev_dbgp_op_t);
346 
347 /*
348  * Notify that some PIRQ-bound event channels have been unmasked.
349  * ** This command is obsolete since interface version 0x00030202 and is **
350  * ** unsupported by newer versions of Xen.                              **
351  */
352 #define PHYSDEVOP_IRQ_UNMASK_NOTIFY      4
353 
354 #if __XEN_INTERFACE_VERSION__ < 0x00040600
355 /*
356  * These all-capitals physdev operation names are superceded by the new names
357  * (defined above) since interface version 0x00030202. The guard above was
358  * added post-4.5 only though and hence shouldn't check for 0x00030202.
359  */
360 #define PHYSDEVOP_IRQ_STATUS_QUERY       PHYSDEVOP_irq_status_query
361 #define PHYSDEVOP_SET_IOPL               PHYSDEVOP_set_iopl
362 #define PHYSDEVOP_SET_IOBITMAP           PHYSDEVOP_set_iobitmap
363 #define PHYSDEVOP_APIC_READ              PHYSDEVOP_apic_read
364 #define PHYSDEVOP_APIC_WRITE             PHYSDEVOP_apic_write
365 #define PHYSDEVOP_ASSIGN_VECTOR          PHYSDEVOP_alloc_irq_vector
366 #define PHYSDEVOP_FREE_VECTOR            PHYSDEVOP_free_irq_vector
367 #define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi
368 #define PHYSDEVOP_IRQ_SHARED             XENIRQSTAT_shared
369 #endif
370 
371 #if __XEN_INTERFACE_VERSION__ < 0x00040200
372 #define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v1
373 #else
374 #define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v2
375 #endif
376 
377 #endif /* __XEN_PUBLIC_PHYSDEV_H__ */
378 
379 /*
380  * Local variables:
381  * mode: C
382  * c-file-style: "BSD"
383  * c-basic-offset: 4
384  * tab-width: 4
385  * indent-tabs-mode: nil
386  * End:
387  */
388