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